以前寫過Python的設計模式,因爲常常不使用Python,回過頭來再看Python的設計模式,有時候感受並非那麼的顯而易見,因此使用c#從新將代碼編寫一遍,更加清晰明瞭。html
這裏借用原來的介紹,對模式作簡要說明,模式簡易說明和類圖,請查看 http://www.cnblogs.com/cotton/category/606629.html程序員
設計模式分爲三種類型算法
建立型模式c#
簡單工廠模式又稱之爲靜態工廠方法,屬於建立型模式。在簡單工廠模式中,能夠根據傳遞的參數不一樣,返回不一樣類的實例。簡單工廠模式定義了一個類,這個類專門用於建立其餘類的實例,這些被建立的類都有一個共同的父類。設計模式
namespace DesignPattern { public class SimpleFactory { public static Operation GetOperation(op op, double a, double b) { switch (op) { case op.add: return new Add(a, b); case op.sub: return new Sub(a, b); case op.mul: return new Mul(a, b); case op.div: return new Div(a, b); default: return new undef(a, b); } } } public enum op { add = '+', sub = '-', mul = '*', div = '/' } public abstract class Operation { public double a, b; public Operation(double a, double b) { this.a = a; this.b = b; } public abstract double GetResult(); } public class Add : Operation { public Add(double a, double b) : base(a, b) { } public override double GetResult() { return a + b; } } public class Sub : Operation { public Sub(double a, double b) : base(a, b) { } public override double GetResult() { return a - b; } } public class Mul : Operation { public Mul(double a, double b) : base(a, b) { } public override double GetResult() { return a * b; } } public class Div : Operation { public Div(double a, double b) : base(a, b) { } public override double GetResult() { try { return a / b; } catch (DivideByZeroException e) { throw e; } } } public class undef : Operation { public undef(double a, double b) : base(a, b) { } public override double GetResult() { throw new NotImplementedException(); } } }
工廠方法模式定義了一個建立對象的接口,但由子類決定要實例化的類是哪個。工廠方法模式讓實例化推遲到子類。緩存
和簡單工廠區別在於,每一個工廠只管生產本身對應的產品,而簡單工廠是一個工廠生產各類產品。ide
namespace DesignPattern { public interface ILogger { void write(string log); } public class EventLogger : ILogger { public void write(string log) { Console.WriteLine("EventLog:" + log); } } public class FileLogger : ILogger { public void write(string log) { Console.WriteLine("FileLog:" + log); } } public interface ILoggerFactory { ILogger CreateLogger(); } public class EventLoggerFactory : ILoggerFactory { public ILogger CreateLogger() { return new EventLogger(); } } public class FileLoggerFactory : ILoggerFactory { public ILogger CreateLogger() { return new FileLogger(); } } }
抽象工廠模式提供一個接口,用於建立相關或者依賴對象的家族,而不須要明確指定具體類。函數
抽象工廠容許客戶端使用抽象的接口來建立一組相關的產品,而不須要關係實際產出的具體產品是什麼。這樣一來,客戶就能夠從具體的產品中被解耦。ui
和工廠方法主要區別於,抽象工廠內要像像定義中說的同樣,‘建立一組相關的產品’。this
感受像是(不知道這樣理解對否):簡單工廠是一個工廠生產多個產品;工廠方法是拆分紅子工廠,分別生產各自產品;抽象工廠整合工廠方法和簡單工廠,隨着子工廠規模變大,也能夠生產多個相似產品。
namespace DesignPattern { //抽象實體 public abstract class absSalary { protected double salary; protected double bonus; protected double tax; public absSalary(double sal, double bns, double t) { this.salary = sal; this.bonus = bns; this.tax = t; } public abstract double CalculateTax(); } public class ChineseSalary : absSalary { public ChineseSalary(double sal, double bns, double t) : base(sal, bns, t) { } public override double CalculateTax() { return (base.salary + base.bonus - 3500) * base.tax; } } public class ForeignerSalary : absSalary { public ForeignerSalary(double sal, double bonus, double tax) : base(sal, bonus, tax) { } public override double CalculateTax() { return (base.salary + base.bonus - 4000) * base.tax; } } public abstract class absSocialSecurity { protected double SocialSecurity; public absSocialSecurity() { this.SocialSecurity = 0; } public virtual double GetSocialSecurity() { return this.SocialSecurity; } } public class ChineseSocialSecurity : absSocialSecurity { public ChineseSocialSecurity(double socialsecurity) : base() { base.SocialSecurity = socialsecurity < 1000 ? 1000 : socialsecurity; } } public class ForeignerSocialSecurity : absSocialSecurity { public ForeignerSocialSecurity(double socialsecurity) : base() { base.SocialSecurity = socialsecurity < 1500 ? 1500 : socialsecurity; } } //抽象工廠,生產一系列產品(多個Create方法,分別對應不一樣產品) public interface AbstractFactory { absSalary CreateSalary(double sal, double bonus, double tax); absSocialSecurity CreateSocialSecurity(double socialsecurity); } public class ChineseFactory : AbstractFactory { public absSalary CreateSalary(double sal, double bonus, double tax) { return new ChineseSalary(sal, bonus, tax); } public absSocialSecurity CreateSocialSecurity(double socialsecurity) { return new ChineseSocialSecurity(socialsecurity); } } public class ForeignerFactory : AbstractFactory { public absSalary CreateSalary(double sal, double bonus, double tax) { return new ForeignerSalary(sal, bonus, tax); } public absSocialSecurity CreateSocialSecurity(double socialsecurity) { return new ForeignerSocialSecurity(socialsecurity); } } }
建造者模式將一個複雜對象的構建與表示分離,使得一樣的構建過程能夠建立不一樣的表示。
建造者模式構建複雜對象就像造汽車同樣,是一個一個組件一個一個步驟建立出來的,它容許用戶經過制定的對象類型和內容來建立他們,可是用戶並不須要知道這個複雜對象是如何構建的,它只須要明白經過這樣作我能夠獲得一個完整的複雜對象實例。
和工廠方法很像,創造者是一個builder內每一個方法分別建立產品零部件,而工廠方法是每一個factory生產一個產品。若是把builder的零部件當作一個完整產品呢?是否是就像 builder又再一次封裝了factory~
namespace DesignPattern { public class Meal { private string food; private string drink; public Meal() { } public void setFood(string food) { this.food = food; } public void setDrink(string drink) { this.drink = drink; } public string getFood() { return this.food; } public string getDrink() { return this.drink; } } //建造者,分別建造不一樣部件,而後返回總體 public abstract class Builder { protected Meal meal = new Meal(); public abstract void buildFood(); public abstract void buildDrink(); public Meal GetMeal() { return meal; } } public class MealABuilder : Builder { public override void buildFood() { meal.setFood("A food"); } public override void buildDrink() { meal.setDrink("A drink"); } } public class MealBBuilder : Builder { public override void buildFood() { meal.setFood("B food"); } public override void buildDrink() { meal.setDrink("B drink"); } } public class Waitor { public void PrepareMeal(Builder builder) { builder.buildDrink(); builder.buildFood(); } } }
所謂原型模式就是用原型實例指定建立對象的種類,而且經過複製這些原型建立新的對象。
說到複製,就會有深/淺兩種複製,這是面向對象的值類型和引用類型的差別,具體不做說明
namespace DesignPattern { [Serializable] public class other { public int value { get; set; } public other() { value = 10; } } [Serializable] public abstract class ColorPrototype { public int red { get; set; } public int green { get; set; } public int blue { get; set; } public other o = new other(); //淺拷貝 public virtual ColorPrototype Clone() { return (ColorPrototype)this.MemberwiseClone(); } } public class Red : ColorPrototype { public override ColorPrototype Clone() { return base.Clone(); } } [Serializable] public class Green : ColorPrototype { public override ColorPrototype Clone() { BinaryFormatter formatter = new BinaryFormatter(); MemoryStream stream = new MemoryStream(); formatter.Serialize(stream, this); stream.Position = 0; ColorPrototype obj = (ColorPrototype)formatter.Deserialize(stream); return obj; } } }
namespace DesignPattern { public class Singleton { private int cnt = 0; private static Singleton instance = null; private volatile static Singleton safeInstance = null; private static readonly object lockedobj = new object(); private Singleton() { } public static Singleton GetInstance() { if (instance == null) instance = new Singleton(); return instance; } public static Singleton GetSafeInstance() { if (safeInstance == null) { lock (lockedobj) { if (safeInstance == null) { safeInstance = new Singleton(); } } } return safeInstance; } public void count() { cnt += 1; } public int getCnt() { return cnt; } } }
結構型模式
適配器模式就是將一個類的接口,轉換成客戶指望的另外一個接口。適配器讓本來接口不兼容的類能夠合做無間。
在適配器模式中,咱們能夠定義一個包裝類,包裝不兼容接口的對象,這個包裝類就是適配器,它所包裝的對象就是適配者。
適配器提供給客戶須要的接口,適配器的實現就是將客戶的請求轉換成對適配者的相應的接口的引用。也就是說,當客戶調用適配器的方法時,適配器方法內部將調用 適配者的方法,客戶並非直接訪問適配者的,而是經過調用適配器方法訪問適配者。由於適配器可使互不兼容的類可以「合做愉快」。
注:此處ILogger接口使用了【工廠方法模式】定義的接口
namespace DesignPattern { public interface IAdaptor { void writelog(string log); } public class LogAdaptor : IAdaptor { ILogger logger; public LogAdaptor(ILogger logger) { this.logger = logger; } public void writelog(string log) { this.logger.write(log); } } }
橋接模式即將抽象部分與它的實現部分分離開來,使他們均可以獨立變化。
橋接模式將繼承關係轉化成關聯關係,它下降了類與類之間的耦合度,減小了系統中類的數量,也減小了代碼量。
我的感受,代理模式、適配器模式和橋接模式相相似,代理模式是一個代理對外表示一個特定的類,適配器模式至關於一個適配器代理多個類,而橋接模式則更加適用於多個對多個的時候
namespace DesignPattern { public abstract class Color { public string name { get; set; } } public abstract class Shape { private Color color; public string name { get; set; } public void SetColor(Color c) { color = c; } public void Draw() { Console.WriteLine("draw shape {0} with color {1}", this.name, this.color.name); } } public class White : Color { public White() { this.name = "white"; } } public class Blue : Color { public Blue() { this.name = "blue"; } } public class Squre : Shape { public Squre() { this.name = "squre"; } } public class Circle : Shape { public Circle() { this.name = "circle"; } } }
裝飾者模式裝飾者模式能夠動態地給一個對象增長一些額外的職責。就增長功能來講,裝飾者模式相比生成子類更爲靈活。
namespace DesignPattern { public abstract class Car { public string color { get; set; } public int compartment { get; set; } public void run() { Console.WriteLine(color + " " + compartment + " compartment " + this.GetType().Name + " is running!"); } } public class Benz:Car { public Benz() { base.color = "black"; base.compartment = 1; } } public class QQ:Car { public QQ() { base.color = "black"; base.compartment = 1; } } public abstract class Decorator : Car { public Car car; public Decorator(Car car) { this.car = car; } } public class ColorDecorator:Decorator { //通常在構造函數內完成屬性的修改(裝飾),這裏單獨加了一個decorate方法 public ColorDecorator(Car car):base(car) { } public Car decorate(string color) { base.car.color = color; return base.car; } } public class CompartmentDecorator : Decorator { public CompartmentDecorator(Car car) : base(car) { } public Car decorate(int compartment) { base.car.compartment = compartment; return base.car; } } }
組合模式組合多個對象造成樹形結構以表示「總體-部分」的結構層次。
組合模式對單個對象(葉子對象)和組合對象(組合對象)具備一致性,它將對象組織到樹結構中,能夠用來描述總體與部分的關係。同時它也模糊了簡單元素(葉 子對象)和複雜元素(容器對象)的概念,使得客戶可以像處理簡單元素同樣來處理複雜元素,從而使客戶程序可以與複雜元素的內部結構解耦。
namespace DesignPattern { public abstract class File { protected string name; public File(string name) { this.name = name; } public abstract void Display(); } public class Folder : File { IList<File> list; public Folder(string name) : base(name) { list = new List<File>(); } public void AddFile(File file) { list.Add(file); } public void RemoveFile(File file) { list.Remove(file); } public override void Display() { Console.WriteLine("folder:" + this.name); foreach (File f in list) { f.Display(); } } } public class ImageFile : File { public ImageFile(string name) : base(name) { } public override void Display() { Console.WriteLine("ImageFile:" + this.name); } } }
所謂外觀模式就是提供一個統一的接口,用來訪問子系統中的一羣接口。
namespace DesignPattern { public class Facade { Light _light = new Light(); TV _tv = new TV(); public void off() { _light.on(); _tv.off(); } public void on() { _tv.on(); _light.off(); } } class Light { public void on() { Console.WriteLine("light on!"); } public void off() { Console.WriteLine("light off!"); } } class TV { public void on() { Console.WriteLine("tv on!"); } public void off() { Console.WriteLine("tv off!"); } } }
所謂享元模式就是運行共享技術有效地支持大量細粒度對象的複用。系統使用少許對象,並且這些都比較類似,狀態變化小,能夠實現對象的屢次複用。
FlyweightFactory內定義的實體是不變的(共享的),傳入參數是狀態變化。
緩存形式,傳入參數已經被緩存則直接返回,不然建立參數對應實體,放入緩存並返回該新實體
namespace DesignPattern { public class FlyweightFactory { static Dictionary<string, IFlyweight> pendic = new Dictionary<string, IFlyweight>(); public IFlyweight getPen(string color) { if (pendic.ContainsKey(color)) { return pendic[color]; } else { IFlyweight pen = new ConcreteFlyweight(color); pendic.Add(color, pen); return pen; } } public void Display() { foreach (KeyValuePair<string,IFlyweight> pair in pendic) { Console.WriteLine(pair.Value.GetType().FullName + ":" + pair.Key); } } } public interface IFlyweight { string GetColor(); }; public class ConcreteFlyweight : IFlyweight { string color; public ConcreteFlyweight(string color) { this.color = color; } public string GetColor() { return this.color; } } }
代理模式就是給一個對象提供一個代理,並由代理對象控制對原對象的引用。
在代理模式中,「第三者」代理主要是起到一箇中介的做用,它鏈接客戶端和目標對象。
namespace DesignPattern { public class Girl { public string name { get; set; } public Girl(string name) { this.name = name; } } public class Boy { private Girl girl; public string name { get; set; } public Boy(string name, Girl girl) { this.name = name; this.girl = girl; } public void GiveFlower() { Console.WriteLine("boy {0} give flower to girl {1}", this.name, this.girl.name); } } public class Proxy { private Boy boy; public Proxy(Boy boy) { this.boy = boy; } public void GiveFlower() { this.boy.GiveFlower(); } } }
行爲型模式
namespace DesignPattern { public class Persons : IEnumerable { string[] m_Names; public Persons(params string[] Names) { m_Names = new string[Names.Length]; Names.CopyTo(m_Names, 0); } public IEnumerator GetEnumerator() { foreach (string s in m_Names) { yield return s; } } public int Length { get { return m_Names.Length; } } public string this[int i] { get { return m_Names[i]; } set { m_Names[i] = value; } } } }
所謂解釋器(Interpreter)就是將一系列指令轉化成代碼,可以執行的代碼。Interpreter原本就有翻譯的意思。GoF給它的定義是:給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
namespace DesignPattern { public class Context { private string msg; public Context(string msg) { this.msg = msg; } public string GetMsg() { return this.msg; } } public interface Interpreter { string Interprete(Context context); } public class UpperInterpreter : Interpreter { public string Interprete(Context context) { string msg = context.GetMsg(); return msg.ToUpperInvariant(); } } public class LowerInterpreter : Interpreter { public string Interprete(Context context) { string msg = context.GetMsg(); return msg.ToLowerInvariant(); } } }
將請求封裝成對象,從而使可用不一樣的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤消的操做。
namespace DesignPattern { //接受命令的對象 public class CDMachine { public void on() { Console.WriteLine("CD Machine turns on!"); } public void off() { Console.WriteLine("CD Machine turns off!"); } } //定義命令 public abstract class Command { public abstract void Execute(CDMachine cdMachine); } public class TurnonCommand : Command { public override void Execute(CDMachine cdMachine) { cdMachine.on(); } } public class TurnoffCommand : Command { public override void Execute(CDMachine cdMachine) { cdMachine.off(); } } //發送命令的對象 public class Controller { //遙控的功能 --- 可發送的命令 private TurnonCommand turnonCommand; private TurnoffCommand turnoffCommand; public Controller(TurnonCommand turnonCommand, TurnoffCommand turnoffCommand) { this.turnonCommand = turnonCommand; this.turnoffCommand = turnoffCommand; } public void turnOn(CDMachine cdMachine) { this.turnonCommand.Execute(cdMachine); } public void turnOff(CDMachine cdMachine) { this.turnoffCommand.Execute(cdMachine); } } }
所謂中介者模式就是用一箇中介對象來封裝一系列的對象交互,中介者使各對象不須要顯式地相互引用,從而使其耦合鬆散,並且能夠獨立地改變它們之間的交互。
namespace DesignPattern { public abstract class Person { public string name; public Mediator mediator; public Person(string name, Mediator mediator) { this.name = name; this.mediator = mediator; } public void Contact(string msg) { //參數 this 表明 消息來自我 this.mediator.SendMsg(msg, this); } internal void GetMsg(string msg) { Console.WriteLine(this.name + " 收到消息:" + msg); } } public class HouseOwner : Person { public HouseOwner(string name, Mediator mediator) : base(name, mediator) { } } public class Tenant : Person { public Tenant(string name, Mediator mediator) : base(name, mediator) { } } public interface Mediator { void SendMsg(string msg, Person p); } public class ConcreteMediator : Mediator { HouseOwner houseOwner; Tenant tenant; public ConcreteMediator() { } public void SetHouseOwner(HouseOwner houseOwner) { this.houseOwner = houseOwner; } public void SetTenant(Tenant tenant) { this.tenant = tenant; } public void SendMsg(string msg, Person p) { if (p.GetType() == houseOwner.GetType()) { tenant.GetMsg(msg); } else { houseOwner.GetMsg(msg); } } } }
所謂備忘錄模式就是在不破壞封裝的前提下,捕獲一個對象的內部狀態,並在該對象以外保存這個狀態,這樣能夠在之後將對象恢復到原先保存的狀態。
namespace DesignPattern { public class Memonto { public int blood { get; set; } public int magic { get; set; } } public class Caretaker { private Memonto memonto; public void SetMemonto(Memonto memonto) { this.memonto = memonto; } public Memonto getMemonto() { return this.memonto; } } public class Original { public int blood { get; set; } public int magic { get; set; } public Memonto SaveMemonto() { return new Memonto() { blood = this.blood, magic = this.magic }; } public void RestoreMemonto(Memonto memonto) { this.blood = memonto.blood; this.magic = memonto.magic; } public void display() { Console.WriteLine("blood:" + this.blood + "\tmagic:" + this.magic); } } }
定義了一種一對多的關係,讓多個觀察對象同時監聽一個主題對象,當主題對象狀態發生變化時會通知全部觀察者。
public interface Observer { void Update(Subject subject); } public abstract class Subject { List<Observer> obsList = new List<Observer>(); public void AddObserver(Observer observer) { obsList.Add(observer); } public void RemoveObserver(Observer observer) { obsList.Remove(observer); } public void notity() { foreach (Observer o in obsList) { o.Update(this); } } private string _state; public void SetState(string state) { this._state = state; } public string GetState() { return this._state; } } public class ConcreteSubject : Subject { } public class ConcreteObserver1 : Observer { public void Update(Subject subject) { Console.WriteLine("ConcreteObserver1 get notice:" + subject.GetState()); } } public class ConcreteObserver2 : Observer { public void Update(Subject subject) { Console.WriteLine("ConcreteObserver2 get notice:" + subject.GetState()); } }
//事件委託的方式 public delegate void updateDelegate(Subject subject); public class EventSubjet : Subject { public event updateDelegate UpdateHandler; public void EventNotify() { OnUpdate(); } private void OnUpdate() { if (UpdateHandler != null) { UpdateHandler(this); } } }
當一個對象的內在狀態改變時容許改變其行爲,這個對象看起來像是改變了其類。
namespace DesignPattern { public interface IState { void display(); } public class WorkState:IState { public void display() { Console.WriteLine("Working State"); } } public class RestState:IState { public void display() { Console.WriteLine("Rest State"); } } public class Programmer { IState _state; public void Doing(DateTime dt) { if(dt.Hour<7 || dt.Hour > 22) { _state = new RestState(); } else { _state = new WorkState(); } _state.display(); } } }
定義一個操做中的算法的骨架,而將步驟延遲到子類中。模板方法使得子類能夠不改變一個算法的結構便可重定義算法的某些特定步驟。
namespace DesignPattern { public abstract class Template { protected void boilWater() { Console.WriteLine("boil water"); } protected virtual void brew() { Console.WriteLine("brew"); } protected void pourInCup() { Console.WriteLine("pour into cup"); } protected virtual void addOther() { Console.WriteLine("add other"); } public void makeBeverage() { boilWater(); brew(); pourInCup(); addOther(); } } public class Tea : Template { protected override void brew() { Console.WriteLine("tea"); } protected override void addOther() { Console.WriteLine("add lemon"); } } public class Coffee : Template { protected override void brew() { Console.WriteLine("coffee"); } protected override void addOther() { Console.WriteLine("add sugar"); } } }
定義算法家族而且分別封裝,它們之間能夠相互替換而不影響客戶端。
namespace DesignPattern { public abstract class OrderStrategy { public List<int> orderList; public abstract void Order(); public void display() { foreach (int i in orderList) { Console.Write(i + "\t"); } Console.WriteLine(); } } public class BubbleStrategy : OrderStrategy { public override void Order() { for (int i = 0; i < orderList.Count; i++) { for (int j = i + 1; j < orderList.Count; j++) { if (orderList[i] < orderList[j])//冒泡降序 小的冒上去 { int temp = orderList[i]; orderList[i] = orderList[j]; orderList[j] = temp; } } } } } public class SelectionStrategy : OrderStrategy { public override void Order() { for (int i = 0; i < orderList.Count; i++) { int smallvalue = orderList[i]; int smallposition = i; for (int j = i + 1; j < orderList.Count; j++) { if (orderList[j] < smallvalue) { smallposition = j; smallvalue = orderList[j]; } } //將最小值放到當前要排序的位置 orderList[smallposition] = orderList[i]; orderList[i] = smallvalue; } } } public class InsertionStrategy : OrderStrategy { public override void Order() { for (int i = 1; i < orderList.Count; i++) { int temp = orderList[i];//當前要插入的值,至關於位置I是個空白位置,供對比進行後移 int j = i; //j以前的序列已經排序好,選一個位置把當前值插入 while (j > 0) { //i從1開始,是由於這裏j要比較前一個值 if (temp < orderList[j - 1]) //插入過程當中,每次比較的值大於當前值則向後移動 { orderList[j] = orderList[j-1]; j--; } else { break; } } //找到位置(break)或者循環正常結束(說明當前值最小)則賦值。 orderList[j] = temp; } } } public class StrategyManager { OrderStrategy strategy; public void SetStrategy(OrderStrategy strategy) { this.strategy =strategy; } public void Sort(List<int> list) { this.strategy.orderList = list; this.strategy.Order(); this.strategy.display(); } } }
訪問者模式即表示一個做用於某對象結構中的各元素的操做,它使咱們能夠在不改變各元素的類的前提下定義做用於這些元素的新操做。
namespace DesignPattern { public interface Element { void accept(Visitor visitor); } public class ConcreteElementA : Element { string name; public void SetName(string name) { this.name = name; } public string GetName() { return this.name; } public void accept(Visitor visitor) { visitor.visitElementA(this); } } public class ConcreteElementB : Element { int ID; public void SetID(int id) { this.ID = id; } public int GetID() { return this.ID; } public void accept(Visitor visitor) { visitor.visitElementB(this); } } public interface Visitor { void visitElementA(ConcreteElementA ea); void visitElementB(ConcreteElementB eb); } public class ConcreteVisitorA : Visitor { public void visitElementA(ConcreteElementA ea) { Console.WriteLine("ConcreteVisitorA visit ElemantA:" + ea.GetName()); } public void visitElementB(ConcreteElementB eb) { Console.WriteLine("ConcreteVisitorA visit ElemantB:" + eb.GetID()); } } public class ConcreteVisitorB : Visitor { public void visitElementA(ConcreteElementA ea) { Console.WriteLine("ConcreteVisitorB visit ElemantA:" + ea.GetName()); } public void visitElementB(ConcreteElementB eb) { Console.WriteLine("ConcreteVisitorB visit ElemantB:" + eb.GetID()); } } public class objectStructure { List<Element> elementlist = new List<Element>(); public void Attach(Element e) { elementlist.Add(e); } public void Dettach(Element e) { elementlist.Remove(e); } public void Accept(Visitor visit) { foreach(Element e in elementlist) { e.accept(visit); } } } }
避免請求發送者與接收者耦合在一塊兒,讓多個對象都有可能接收請求,將這些對象鏈接成一條鏈,而且沿着這條鏈傳遞請求,直到有對象處理它爲止,這就是職責鏈模式。
namespace DesignPattern { public class Request { int days; string name; public Request(int days, string name) { this.days = days; this.name = name; } public int GetDays() { return days; } public string GetName() { return name; } } public abstract class Responsibility { protected Responsibility responsibility; public Responsibility(Responsibility responsibility) { this.responsibility = responsibility; } public abstract void HandleRequest(Request request); } public class Leader : Responsibility { public Leader(Responsibility responsibility) : base(responsibility) { } public override void HandleRequest(Request request) { if (request.GetDays() < 3) { Console.WriteLine("Leader passed {0}'s {1} days request", request.GetName(), request.GetDays()); } else { this.responsibility.HandleRequest(request); } } } public class Department : Responsibility { public Department(Responsibility responsibility) : base(responsibility) { } public override void HandleRequest(Request request) { if (request.GetDays() < 8) { Console.WriteLine("Department passed {0}'s {1} days request", request.GetName(), request.GetDays()); } else { this.responsibility.HandleRequest(request); } } } //責任鏈終端必須處理 public class Boss : Responsibility { public Boss() : base(null) { } public override void HandleRequest(Request request) { if (request.GetDays() < 15) { Console.WriteLine("Boss passed {0}'s {1} days request", request.GetName(), request.GetDays()); } else { Console.WriteLine("Boss refused {0}'s {1} days request", request.GetName(), request.GetDays()); } } } }
namespace DesignPattern { class Program { static void Main(string[] args) { //簡單工廠 Console.WriteLine("簡單工廠"); Console.WriteLine(SimpleFactory.GetOperation(op.add, 1.1, 2.2).GetResult()); //工廠方法 Console.WriteLine("\n工廠方法"); ILoggerFactory factorymethod = new EventLoggerFactory(); ILogger iLogger = factorymethod.CreateLogger(); iLogger.write("123"); factorymethod = new FileLoggerFactory(); iLogger = factorymethod.CreateLogger(); iLogger.write("321"); //抽象工廠 Console.WriteLine("\n抽象工廠"); AbstractFactory absFactory = new ChineseFactory(); absSalary chSalary = absFactory.CreateSalary(10000, 8000, 0.12); absSocialSecurity chScSc = absFactory.CreateSocialSecurity(1200); Console.WriteLine(chSalary.CalculateTax()); Console.WriteLine(chScSc.GetSocialSecurity()); absFactory = new ForeignerFactory(); chSalary = absFactory.CreateSalary(10000, 8000, 0.12); chScSc = absFactory.CreateSocialSecurity(1200); Console.WriteLine(chSalary.CalculateTax()); Console.WriteLine(chScSc.GetSocialSecurity()); //創造者模式 Console.WriteLine("\n創造者模式"); Waitor waiter = new Waitor(); Builder b1 = new MealABuilder(); Builder b2 = new MealBBuilder(); waiter.PrepareMeal(b1); Meal ma = b1.GetMeal(); Console.WriteLine(ma.getFood() + "\t" + ma.getDrink()); waiter.PrepareMeal(b2); Meal mb = b2.GetMeal(); Console.WriteLine(mb.getFood() + "\t" + mb.getDrink()); //原型模式 Console.WriteLine("\n原型模式"); Red r = new Red(); r.o.value = 20;//改變引用值 ColorPrototype RCopy = r.Clone(); RCopy.o.value = 30; Console.WriteLine(r.o.value);//30 淺拷貝,指向同一個應用對象,一處改變,都改變 Green g = new Green(); g.o.value = 20; ColorPrototype GCopy = g.Clone(); GCopy.o.value = 30; Console.WriteLine(g.o.value);//20 深拷貝,引用對象獨立 //單例模式 Console.WriteLine("\n單例模式"); Task[] tArr = new Task[]{ Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()), Task.Run(() => Singleton.GetInstance().count()) }; Singleton.GetInstance().count(); Task.WaitAll(tArr); Console.WriteLine("danger:" + Singleton.GetInstance().getCnt()); Task[] tArrSafe = new Task[]{ Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()), Task.Run(() => Singleton.GetSafeInstance().count()) }; Singleton.GetSafeInstance().count(); Task.WaitAll(tArrSafe); Console.WriteLine("safe:" + Singleton.GetSafeInstance().getCnt()); //迭代器 Console.WriteLine("\n迭代器"); Persons ps = new Persons(new string[] { "1", "2", "3" }); foreach (string name in ps) { Console.WriteLine(name); } for (var i = 0; i < ps.Length; i++) { Console.WriteLine(ps[i]); } //適配器模式 Console.WriteLine("\n適配器模式"); EventLogger eLog = new EventLogger(); FileLogger fLog = new FileLogger(); LogAdaptor adapter = new LogAdaptor(eLog); adapter.writelog("123123"); adapter = new LogAdaptor(fLog); adapter.writelog("123123"); //代理模式 Console.WriteLine("\n代理模式"); Girl girl = new Girl("Han MeiMei"); Boy boy = new Boy("Li Lei", girl); Proxy proxy = new Proxy(boy); proxy.GiveFlower(); //橋接模式 Console.WriteLine("\n橋接模式"); Color blue = new Blue(); Color white = new White(); Shape squre = new Squre(); Shape circle = new Circle(); squre.SetColor(blue); squre.Draw(); circle.SetColor(white); circle.Draw(); //組合模式 Console.WriteLine("\n組合模式"); Folder folder1 = new Folder("study"); File img = new ImageFile("img"); folder1.AddFile(img); Folder folder2 = new Folder("c#"); folder2.AddFile(img); folder1.AddFile(folder2); folder1.Display(); //解釋器模式 Console.WriteLine("\n解釋器模式"); Context context = new Context("ABcdeFG"); UpperInterpreter ui = new UpperInterpreter(); string inprResut = ui.Interprete(context); Console.WriteLine("up:" + inprResut); LowerInterpreter li = new LowerInterpreter(); inprResut = li.Interprete(context); Console.WriteLine("low:" + inprResut); //外觀模式 Console.WriteLine("\n外觀模式"); Facade facade = new Facade(); Console.WriteLine("電視打開,電燈關閉!"); facade.on(); Console.WriteLine("3秒後電燈打開,電視關閉"); Thread.Sleep(3000); facade.off(); //享元模式 Console.WriteLine("\n享元模式"); FlyweightFactory flyfactory = new FlyweightFactory(); IFlyweight flyweidht = flyfactory.getPen("red"); Console.WriteLine(flyweidht.GetColor()); flyweidht = flyfactory.getPen("blue"); Console.WriteLine(flyweidht.GetColor()); flyweidht = flyfactory.getPen("red"); Console.WriteLine(flyweidht.GetColor()); flyfactory.Display(); //責任鏈模式 Console.WriteLine("\n責任鏈模式"); Request request = new Request(20, "wang"); Boss boss = new Boss(); Department department = new Department(boss); Leader leader = new Leader(department); leader.HandleRequest(request); //命令模式 Console.WriteLine("\n命令模式"); CDMachine cd = new CDMachine(); TurnoffCommand off = new TurnoffCommand(); TurnonCommand on = new TurnonCommand(); Controller ctrl = new Controller(on, off); //遙控器發送命令到cd機 ctrl.turnOn(cd); ctrl.turnOff(cd); //中介者模式 Console.WriteLine("\n中介者模式"); //中介單獨存在 //Mediator mediator = new ConcreteMediator(); ConcreteMediator mediator = new ConcreteMediator(); //房主和租客尋找中介 HouseOwner houseOwner = new HouseOwner("houseowner", mediator); Tenant tenant = new Tenant("tenant", mediator); //中介給他們搭建連接 mediator.SetHouseOwner(houseOwner); mediator.SetTenant(tenant); houseOwner.Contact("出租房"); tenant.Contact("租房"); //備忘錄模式 Console.WriteLine("\n備忘錄模式"); Caretaker caretaker = new Caretaker(); Original original = new Original(); original.blood = 100; original.magic = 100; original.display(); caretaker.SetMemonto(original.SaveMemonto()); original.blood = 50; original.magic = 50; original.display(); original.RestoreMemonto(caretaker.getMemonto()); original.display(); //觀察者模式 Console.WriteLine("\n觀察者模式"); Subject subject = new ConcreteSubject(); subject.SetState("start"); Observer o1 = new ConcreteObserver1(); Observer o2 = new ConcreteObserver2(); subject.AddObserver(o1); subject.AddObserver(o2); subject.notity(); subject.SetState("change"); subject.notity(); //Subject eventSubject = new EventSubjet(); EventSubjet eventSubject = new EventSubjet(); eventSubject.UpdateHandler += o1.Update; eventSubject.UpdateHandler += o2.Update; eventSubject.SetState("event"); eventSubject.EventNotify(); //狀態模式 Console.WriteLine("\n狀態模式"); Programmer programmer = new Programmer(); Console.WriteLine(DateTime.Now + "程序員正在作什麼呢?"); programmer.Doing(DateTime.Now); Console.WriteLine(DateTime.Now.AddHours(-10) + "程序員正在作什麼呢?"); programmer.Doing(DateTime.Now.AddHours(-10)); //策略模式 Console.WriteLine("\n策略模式"); BubbleStrategy bubble = new BubbleStrategy(); SelectionStrategy selection = new SelectionStrategy(); InsertionStrategy insertion = new InsertionStrategy(); var list = new List<int>() { 3, 1, 6, 2, 5 }; StrategyManager manager = new StrategyManager(); manager.SetStrategy(bubble); manager.Sort(list); manager.SetStrategy(selection); manager.Sort(list); manager.SetStrategy(insertion); manager.Sort(list); //模板模式 Console.WriteLine("\n模板模式"); Template tea = new Tea(); tea.makeBeverage(); Template coffee = new Coffee(); coffee.makeBeverage(); //訪問者模式 Console.WriteLine("\n訪問者模式"); ConcreteElementA elementA = new ConcreteElementA(); elementA.SetName("ea"); ConcreteElementB elementB = new ConcreteElementB(); elementB.SetID(2); objectStructure structure = new objectStructure(); structure.Attach(elementA); structure.Attach(elementB); Visitor visitorA = new ConcreteVisitorA(); Visitor visitorB = new ConcreteVisitorB(); structure.Accept(visitorA); structure.Accept(visitorB); //裝飾者模式 Console.WriteLine("\n裝飾者模式"); Car car = new Benz(); car = new ColorDecorator(car).decorate("red"); car.run(); car = new CompartmentDecorator(car).decorate(3); car.run(); } } }
該博文出發點是使用面向對象的語言,使用簡單的示例簡要歸納說明各個模式的應用,已備不時之需。
提交了一次居然沒經過,從首頁移除
從新發送一遍,是否是能經過呢?
爲避免某某些摺疊代碼不能正常打開,附源碼下載地址