實現一個相似QQavator功能的代碼設計模式
一、原始實現ide
1 //存在的問題: 2 //一、wear*方法出現重複代碼,能夠重構;實質上爲代碼結構一致,輸出內容相同,能夠經過在定義一個基類,在基類中定義抽象的Wear*,在子類中重寫; 3 //二、假若需求中新增某種服飾,須要修改Person類代碼,不符合開放——封閉原則; 4 //三、客戶端中代碼暴露了具體裝飾細節,理想狀況下只須要提供裝飾順序,裝飾細節封裝起來; 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解決,使用運行時的多態; 3 //二、問題2解決,增長新的服飾,繼承之; 4 //三、問題3解決,裝飾細節在客戶端隱藏爲一個Wear方法,客戶端僅僅須要搭建起裝飾鏈; 5 //四、面向對象特徵:繼承、運行時的多態、里氏原則使用(41行代碼)統一了子類一樣操做的代碼、 6 //五、Console.WriteLine仍是存在子類中重複,可否進一步優化? 7 //六、客戶端與超類、子類均存在聯繫,可否有必要使用工廠模式? 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 }
3、總結 this
一、設計模式解決什麼問題?
答:裝飾模式把「類中裝飾功能從類中搬移去除,這樣能夠簡化原有的類」、「有效地把類的核心職責和裝飾功能區分開了。並且能夠去除相關的裝飾邏輯」;spa
二、經過什麼手段達到效果?
答:裝飾模式將一個個欲裝飾的功能放在單獨的類中,達到容易拓展的效果;使用運行時多態把子類中相同的裝飾邏輯統一抽離在基類當中,避免了重複代碼;設計
三、應用場景以及約束條件?
答:須要爲已有功能動態添加更多功能時候;
約束條件:裝飾類彼此之間獨立;裝飾順序很重要(相較於建造者模式,不穩定);code
四、符合面向對象哪幾條原則?
答:里氏替換、開放-封閉、單一職責;對象
五、不使用設計模式的代碼弊端在哪?
答:見代碼blog
六、改變需求,對使用設計模式的代碼的健壯性、可維護性、可拓展性檢驗;繼承