实现一个类似QQavator功能的代码
1、原始实现
1 //存在的问题: 2 //1、wear*方法出现重复代码,可以重构;实质上为代码结构一致,输出内容相同,可以通过在定义一个基类,在基类中定义抽象的Wear*,在子类中重写; 3 //2、倘若需求中新增某种服饰,需要修改Person类代码,不符合开放——封闭原则; 4 //3、客户端中代码暴露了具体装饰细节,理想情况下只需要提供装饰顺序,装饰细节封装起来; 5 class Person 6 { 7 private string name; 8 private Listclothing=new List (); 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 : Person26 {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 : ComponetA45 {46 public override void Wear()47 {48 base.Wear();49 Console.WriteLine("犀利哥牌——破洞牛仔裤");50 }51 }52 class Shoes : ComponetA53 {54 public override void Wear()55 {56 base.Wear();57 Console.WriteLine("犀利哥牌——牛皮靴子");58 }59 }60 class RedTshirt : ComponetA61 {62 public override void Wear()63 {64 base.Wear();65 Console.WriteLine("犀利哥牌——墨绿T恤");66 }67 68 }69 class programmer70 {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、改变需求,对使用设计模式的代码的健壮性、可维护性、可拓展性检验;