实现一个类似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、改变需求,对使用设计模式的代码的健壮性、可维护性、可拓展性检验;