当前位置: 首页 > news >正文

【笔记】设计模式——装饰者模式

实现一个类似QQavator功能的代码

1、原始实现

 1  //存在的问题:
 2     //1、wear*方法出现重复代码,可以重构;实质上为代码结构一致,输出内容相同,可以通过在定义一个基类,在基类中定义抽象的Wear*,在子类中重写;
 3     //2、倘若需求中新增某种服饰,需要修改Person类代码,不符合开放——封闭原则;
 4     //3、客户端中代码暴露了具体装饰细节,理想情况下只需要提供装饰顺序,装饰细节封装起来;
 5     class Person
 6     {
 7         private string name;
 8         private List<string> clothing=new List<string>();
 9         public Person(string name)
10         {
11             this.name = name;
12             clothing.Add("裸体帅哥一枚");
13         }
14         public void WearJeans()
15         {
16             clothing.Add("犀利哥牌——破洞牛仔裤");
17         }
18         public void WearRedTshirt()
19         {
20             clothing.Add("犀利哥牌——墨绿T恤");
21         }
22         public void WearShoes()
23         {
24             clothing.Add("犀利哥牌——牛皮靴子");
25         }
26         public void Show()
27         {
28 
29             Console.WriteLine("大家好,请叫我帅哥{0},今天精心打扮了下,你看我这打扮潮流不?", name);
30             foreach (var item in clothing)
31             {
32                 Console.WriteLine("{0}", item);
33             }
34         }
35 
36         public static void Main(string[] args)
37         {
38             Person person = new Person("犀利哥");
39             person.WearRedTshirt();
40             person.WearJeans();
41             person.WearShoes();
42             person.Show();
43         }

二 改进代码

  

 1  //分析:
 2     //1、问题1解决,使用运行时的多态;
 3     //2、问题2解决,增加新的服饰,继承之;
 4     //3、问题3解决,装饰细节在客户端隐藏为一个Wear方法,客户端仅仅需要搭建起装饰链;
 5     //4、面向对象特征:继承、运行时的多态、里氏原则使用(41行代码)统一了子类同样操作的代码、
 6     //5、Console.WriteLine还是存在子类中重复,能否进一步优化?
 7     //6、客户端与超类、子类均存在联系,能否有必要使用工厂模式?
 8     class Person
 9     {
10         protected string name;
11         public Person()
12         {
13         }
14         public Person(string name)
15         {
16             this.name = name;
17         }
18         public virtual void Wear()
19         {
20             Console.WriteLine("大家好,请叫我帅哥{0},今天精心打扮了下,你看我这打扮潮流不?", name);
21         }
22        
23     }
24    
25     class ComponetA : Person
26     {
27         protected Person com = null;
28          public void  SetComponetA(Person com)
29         {
30             if (com!=null)
31             {
32                 this.com = com;
33             }
34         }
35         public override void Wear()
36         {
37             if (com!=null)
38             {
39                 com.Wear();
40             }
41         }
42         
43     }
44     class Jeans : ComponetA
45     {
46         public override void Wear()
47         {
48             base.Wear();
49            Console.WriteLine("犀利哥牌——破洞牛仔裤");
50         }
51     }
52     class Shoes : ComponetA
53     {
54         public override void Wear()
55         {
56             base.Wear();
57             Console.WriteLine("犀利哥牌——牛皮靴子");
58         }
59     }
60     class RedTshirt : ComponetA
61     {
62         public override void Wear()
63         {
64             base.Wear();
65             Console.WriteLine("犀利哥牌——墨绿T恤");
66         }
67         
68     }
69     class  programmer
70     {
71         public static void Main(string[] args)
72         {
73             Person person = new Person("犀利哥");
74             Jeans jeans = new Jeans();
75             Shoes shoes = new Shoes();
76             RedTshirt redTshirt = new RedTshirt();
77             jeans.SetComponetA(person);
78             shoes.SetComponetA(jeans);
79             redTshirt.SetComponetA(shoes);
80             redTshirt.Wear();
81         }
82     }

三、总结  

1、设计模式解决什么问题?
答:装饰模式把“类中装饰功能从类中搬移去除,这样可以简化原有的类”、“有效地把类的核心职责和装饰功能区分开了。而且可以去除相关的装饰逻辑”;


2、通过什么手段达到效果?
答:装饰模式将一个个欲装饰的功能放在单独的类中,达到容易拓展的效果;使用运行时多态把子类中相同的装饰逻辑统一抽离在基类当中,避免了重复代码;


3、应用场景以及约束条件?
答:需要为已有功能动态添加更多功能时候;
约束条件:装饰类彼此之间独立;装饰顺序很重要(相较于建造者模式,不稳定);


4、符合面向对象哪几条原则?
答:里氏替换、开放-封闭、单一职责;


5、不使用设计模式的代码弊端在哪?
答:见代码


6、改变需求,对使用设计模式的代码的健壮性、可维护性、可拓展性检验;

转载于:https://www.cnblogs.com/Jnw-qianxi/p/3707993.html

相关文章:

  • IsBadStringPtr、IsBadWritePtr
  • OC语言BLOCK和协议
  • js学习记录
  • C++容器操作
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • 引用动态链接库Dll文件 引用失败 未能添加对HD.dll的引用。请确保此文件可访问并且是一个有效的程序集或COM组件...
  • IOS 基于APNS消息推送原理与实现(JAVA后台)--转
  • asp.net解决:当前上下文中不存在名称“Session”
  • thinkphp问题记录phpQuery使用错误
  • CTreeCtrl 父结点联动子结点CheckBox
  • Subversion--Version Control
  • SQLPlus命令详细说明
  • ubuntu1304无法启动桌面系统的问题和解决
  • Java反射----数组操作
  • ubuntu12编译openwrt
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • 【Linux系统编程】快速查找errno错误码信息
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • git 常用命令
  • JavaScript对象详解
  • js 实现textarea输入字数提示
  • js作用域和this的理解
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • ViewService——一种保证客户端与服务端同步的方法
  • vue和cordova项目整合打包,并实现vue调用android的相机的demo
  • - 概述 - 《设计模式(极简c++版)》
  • 高程读书笔记 第六章 面向对象程序设计
  • 给初学者:JavaScript 中数组操作注意点
  • 基于Dubbo+ZooKeeper的分布式服务的实现
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 突破自己的技术思维
  • 小程序开发之路(一)
  • 一天一个设计模式之JS实现——适配器模式
  • 【运维趟坑回忆录】vpc迁移 - 吃螃蟹之路
  • # .NET Framework中使用命名管道进行进程间通信
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • #etcd#安装时出错
  • #我与Java虚拟机的故事#连载03:面试过的百度,滴滴,快手都问了这些问题
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • $.each()与$(selector).each()
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (C语言)编写程序将一个4×4的数组进行顺时针旋转90度后输出。
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (env: Windows,mp,1.06.2308310; lib: 3.2.4) uniapp微信小程序
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (板子)A* astar算法,AcWing第k短路+八数码 带注释
  • (附源码)计算机毕业设计ssm本地美食推荐平台
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (删)Java线程同步实现一:synchronzied和wait()/notify()
  • (四)linux文件内容查看
  • (已解决)什么是vue导航守卫
  • (译)2019年前端性能优化清单 — 下篇
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .netcore 6.0/7.0项目迁移至.netcore 8.0 注意事项