###### tags: `Code Sense` `Design-Pattern` # Pattern-Strategy ## 簡介 近期開始整理之前所用Pattern,Strategy為Pattern使用常見的一種,屬於Behavioral Patterns的其中一種 > Behavioral design patterns are concerned with algorithms and the assignment of responsibilities between objects. 策略一般使用情境在於若方法在實作上有所不同,則會宣告介面分別讓物件去實作。而我們要換實作方法時,直接可在Context則可直接抽換或者在DI直接做抽換。 ## 使用情境與實作 近期寫國家儀器溝通時看到一段程式碼,原本儀器溝通使用的方法是GPIB溝通,後續加了Usb溝通方式,Gpib溝通使用的是Ni的Vias dll檔的MessageBasedSession Class而Usb溝通方式使用Ni N4882 dll檔的Device Class。 以前寫結構化程式的自己直覺會直接的使用變數去切換溝通,如下述程式第5行,結果就會看到在每個方法都需要做一次判斷(29,43行)。如果此時又多一個新的溝通方式,例如TCP,則我們則須對此NormalBaseDevice做大調整(每個function都需要更動) ```= public class NormalBaseDevice { private bool IsGpib; // Gpib Com MessageBasedSession GpibCom; // Usb Com Device UsbCom; public NormalBaseDevice(bool isGPIB) { IsGpib = isGPIB; if (isGPIB) { GpibCom = new MessageBasedSession(); } else { UsbCom = new Device(); } } public string Write(string cmd) { if (IsGpib) { return GpibCom.Write(cmd); } else { return UsbCom.Write(cmd); } } public int Read() { if (IsGpib) { return GpibCom.Read(); } else { return UsbCom.Read(); } } } ``` 這種寫法讓所有溝通方法耦合在一起,若要做調整必然有一定程度的影響。此時我們可以以介面去做隔離,讓每種溝通方法去實作介面,在Context使用上就可直接做調整。 我們先宣告一IStrategy介面,宣告Wirte與Read的介面方法如下 ```= public interface IStrategy { string Write(string cmd); int Read(); } ``` 接著撰寫GpibCom與UsbCom Concrete class並實作IStrategy方法。 ```= public class GpibCom : IStrategy { private MessageBasedSession Device; public GpibCom() { Device = new MessageBasedSession(); } public string Write(string cmd) { return Device.Write(cmd); } public int Read() { return Device.Read(); } } ``` ```= public class UsbCom : IStrategy { private Device Device; public UsbCom() { Device = new Device(); } public string Write(string cmd) { return Device.Write(cmd); } public int Read() { return Device.Read(); } } ``` 此時我們在Context就可以隨意抽換我們要的方法,如下 ```= class Program { static void Main(string[] args) { IStrategy com; com = new GpibCom(); var cmd = com.Write(Action); com = new UsbCom(); var cmd = com.Write(Action); } } ``` 另外,策略一般很常搭簡單工廠去包裝Switch選擇要實體化哪個物件。如下 ```= public class ComFacotry { public enum ComType { Gpib, Usb} public static IStrategy CreateCom(ComType type) { IStrategy com; switch (type) { case ComType.Gpib: com = new GpibCom(); break; default: com = new UsbCom(); break; } return com; } } ``` Context使用則變變成 ```= class Program { static void Main(string[] args) { var usbCom = ComFacotry.CreateCom(ComType.Usb); var cmd = usbCom.Write(Action); } } ``` [SourceCode](https://github.com/spyua/hackmdDocCode.git) in CSharpDummyPratice/CSharpDummyCode/DesignPattern/Strategy/
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up