...待續....
不知道聊到設計模式, 經常給人兩種感覺:
1. 原來這個就是A設計模式呀, 我之前也經常這麼幹, 就是到現在才知道A設計模式指的就是這個.
2. 這個B設計模式, 雖然書上講的晦澀難懂, 但我還是勉強理解了, 可是平時基本上用不著, 不知道啥時候改用, 甚至有時候感覺這是在"過度設計".
今天就以一個插排為例來展開學習一下.
需求: 實現一個插排( 就叫它Output吧 , 英文Socket容易引起歧義 ) 的功能 , 它有N組插孔, 支援多個電器的插頭(對應著叫Input吧)插入並供電.
如下圖
............
需求分析:
1. 插排中有一個集合(即多組插孔), 並提供插頭插入(Add)和拔出(Remove)的方法.
2. 插入和拔出的插頭(引數)需要滿足一定的規則, 大家都知道不同國家的插座標準好多不一樣的,比如電壓和針腳的間距等, 這裡就按中國標準吧, 我們也弄個GB.
好的, 根據第一感覺開始coding....
一. 首先定義一個國標(GB)標準, 只有符合此標準的電器才能插入. abstract的"電器"類GBElectricalAppliance.
它有個插頭的功能即 Input 方法,Input方法有兩個引數 left 和 right 象徵插頭的兩個針腳.
1 public abstract class GBElectricalAppliance 2 { 3 public abstract void Input(int left, int right); 4 }
二. 寫個插排(Output)類
1 public class OutPut 2 { 3 public OutPut() 4 { 5 this.EACollection = new List<GBElectricalAppliance>(); 6 } 7 private List<GBElectricalAppliance> EACollection; 8 public void powered(int left,int right) 9 { 10 foreach (var item in EACollection) 11 { 12 item.Input(left,right); 13 } 14 } 15 public void AddInput(GBElectricalAppliance item) 16 { 17 EACollection.Add(item); 18 } 19 20 public void RemoveInput(GBElectricalAppliance item) 21 { 22 EACollection.Remove(item); 23 } 24 }
此類有個private 的集合 EACollection, 兩個Public的方法AddInput和RemoveInput 方法引數為GBElectricalAppliance, 即只支援符合標準的插頭插拔.
當插排Output供電(方法powered)時, 遍歷集和EACollection, 呼叫集和中的電器的Input方法為電器供電.
三. 分別定義一個電視TV和電水壺ElectricKettle繼承此類並實現插頭的功能即 Input 方法.
1 public class TV : GBElectricalAppliance 2 { 3 public override void Input(int left, int right) 4 { 5 Show(); 6 Sound(); 7 } 8 9 private void Show() 10 { 11 Console.WriteLine("I am showing"); 12 } 13 private void Sound() 14 { 15 Console.WriteLine("I am sounding"); 16 } 17 } 18 19 public class ElectricKettle : GBElectricalAppliance 20 { 21 public override void Input(int left, int right) 22 { 23 Heat(); 24 } 25 26 private void Heat() 27 { 28 Console.WriteLine("I am heating"); 29 } 30 }
Main方法測試一下:
輸出:
I am showing
I am sounding
I am heating
四. 小結
到此為止, 功能基本實現了, 我們還可以定義充電寶、電燈等"電器"繼承GBElectricalAppliance插入.
仔細回味一下, 這其實是用到了觀察者模式,
觀察者(電器)將插頭註冊到被觀察者(插排)的集和中, 當被插排供電後, 插排會通知所有註冊到集和中的插頭進行供電.
插排不關心插上的具體是什麼電器, 只要它是符合國標的電器即可. 通過這樣的設計儘量降低插座與電器之間的耦合度.
以上寫法差不多是看到需求後按照第一感覺實現的, 仔細想想我們是不是可以用介面、委託什麼的改造一下,
下一篇文章我們繼續討論.