最近把《大話設計模式》重溫了下(看完序才知道原來做者是也是博客園園友,這本書的最先博客版本在這裏)。體會最深的就是面向接口編程的重要性,如何在本身的項目中進行抽象,合理的利用各類設計模式。怎麼樣儘量屏蔽switch分支、各類if else判斷。具體還得本身品味,體會!整理各個模式的Demo,讓不是很瞭解設計模式的小夥伴迅速有一個大概印象,也方便之後本身查閱。聽說點讚的夥伴最近都能加薪,雙11前,單身的小夥伴能順利脫單~~pull Githtml
一、簡單工廠模式:git
1 namespace ConsoleApplication1 2 { 3 class 簡單工廠模式 4 { 5 public void Main() 6 { 7 var oper = Factory.GetOperat("1"); 8 oper.NumberA = 10; 9 oper.NumberB = 5; 10 oper.GetResult(); 11 } 12 } 13 abstract class Operat 14 { 15 public double NumberA { get; set; } 16 public double NumberB { get; set; } 17 public virtual double GetResult() 18 { 19 return 0; 20 } 21 } 22 class Add : Operat 23 { 24 public override double GetResult() 25 { 26 return NumberA + NumberB; 27 } 28 } 29 class Sub : Operat 30 { 31 public override double GetResult() 32 { 33 return this.NumberA - this.NumberB; 34 } 35 } 36 /// <summary> 37 /// 工廠類 38 /// </summary> 39 class Factory 40 { 41 42 public static Operat GetOperat(string flag) 43 { 44 switch (flag) 45 { 46 case "1": 47 return new Add(); 48 case "2": 49 return new Sub(); 50 default: 51 return null; 52 } 53 } 54 } 55 }
二、策略模式github
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 什麼是策略模式? 5 /// 策略模式就是在簡單工廠模式的基礎上,對factory內部同時封裝具體的子類的方法實現, 6 /// 可是策略模式和工廠模式 仍是沒從根本上消除switch語句 7 /// </summary> 8 class 策略模式 9 { 10 public void Main() 11 { 12 var c = new Context_Cl("1"); 13 c.GetResult(1,6);//這裏調用相對於簡單工廠模式就更加統一了 14 } 15 } 16 abstract class Operat_Cl 17 { 18 public double NumberA { get; set; } 19 public double NumberB { get; set; } 20 21 public virtual double GetResult() 22 { 23 return 0; 24 } 25 } 26 class Add_Cl:Operat_Cl 27 { 28 public Add_Cl(double numberA, double numberB) 29 { 30 } 31 public Add_Cl() 32 {} 33 public override double GetResult() 34 { 35 return NumberA+NumberB; 36 } 37 } 38 class Sub_Cl:Operat_Cl 39 { 40 public override double GetResult() 41 { 42 return NumberA-NumberB; 43 } 44 } 45 class Context_Cl 46 { 47 public Operat_Cl oper { get; set; } 48 public Context_Cl(string flag) 49 { 50 switch (flag) 51 { 52 case "1": 53 oper=new Add_Cl(); 54 break; 55 case "2": 56 oper=new Sub_Cl(); 57 break; 58 default:; 59 break; 60 } 61 } 62 public void GetResult(double numberA,double numberB) 63 { 64 oper.NumberA = numberA; 65 oper.NumberB = numberB; 66 oper.GetResult(); 67 } 68 }
三、裝飾模式sql
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 什麼是裝飾模式:動態的給一個對象添加一些額外的職責。 5 /// 用法:有一個類A實現了一個接口Ia,能夠將一個類B實現了接口Ib,同時定義一個AddAAbout方法和Ia屬性,用該方法接收一個實現了接口Ia的類,而後在類B內 調用A的方法或者屬性。 6 /// </summary> 7 class 裝飾模式 8 { 9 public void Main() 10 { 11 } 12 } 13 /// <summary> 14 /// 抽象對象接口 15 /// </summary> 16 abstract class House 17 { 18 public abstract void Show(); 19 } 20 /// <summary> 21 /// 22 /// </summary> 23 class PingFangHouse:House 24 { 25 public override void Show() 26 { 27 Console.WriteLine("這是平房"); 28 } 29 } 30 /// <summary> 31 /// 32 /// </summary> 33 abstract class LouFangHouse:House 34 { 35 public override void Show() 36 { 37 Console.WriteLine("這是樓房"); 38 } 39 } 40 class OuStyle:House 41 { 42 private House House;//一、將可能須要的一些別的類的定義在本身的類中, 43 public override void Show() 44 { 45 Console.WriteLine("這是歐式風格"); 46 if(House!=null)//調用經過AddStyle方法傳進來的類的方法,就對類OuStyle實現了動態添加方法職能 47 House.Show(); 48 } 49 public void AddStyle(House house)//二、經過動態添加特定的實現了接口House的類,給OuStyle添加特定的實現了House接口的類, 50 { 51 this.House = house; 52 } 53 } 54 /// <summary> 55 /// 因爲這四個類都實現了House接口,因此能夠進一步的將OuStyle對象經過AddSytle方法傳遞給ChinaStyleHouse對象 56 /// </summary> 57 class ChinaStyleHouse:House 58 { 59 private House House; 60 public override void Show() 61 { 62 Console.Write("這是中式風格"); 63 if(House!=null) 64 House.Show(); 65 } 66 public void AddStyle(House house) 67 { 68 this.House = house; 69 } 70 } 71 }
四、代理模式數據庫
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 什麼是代理模式:原本有一個類A能夠直接執行本身的方法就能夠實現一個功能,如今先將這個類A做爲一個屬性傳遞給一個代理類,代理類在經過本身的方法調用A對象的方法,同時能夠添加一些新的功能 5 /// 爲其餘對象提供一種代理,用來控制對這個對象的訪問。 6 /// </summary> 7 class _7_代理模式 8 { 9 public void Main() 10 { 11 } 12 } 13 14 public interface IGiveGift 15 { 16 void GiveDolls(); 17 void GiveFlowers(); 18 } 19 public class Pursuit:IGiveGift 20 { 21 public void GiveDolls() 22 { 23 Console.Write("Give Dolls"); 24 } 25 public void GiveFlowers() 26 { 27 Console.Write("Give Flowers"); 28 } 29 } 30 public class Proxy:IGiveGift 31 { 32 private IGiveGift IGift; 33 public Proxy(IGiveGift iGift) 34 { 35 this.IGift = iGift; 36 } 37 public void GiveDolls() 38 { 39 IGift.GiveFlowers(); 40 Console.WriteLine("proxy can do some badthing in this lol"); 41 } 42 public void GiveFlowers() 43 { 44 IGift.GiveFlowers(); 45 Console.WriteLine("hello beauty,the flower is mine,not his"); 46 } 47 } 48 }
五、工廠方法模式編程
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 工廠模式存在類與switch語句的高耦合,增長新的類 須要去增長case分支,違背了開放-封閉原則 5 /// 工廠方法模式能夠解決這個問題。 6 /// </summary> 7 class 工廠方法模式 8 { 9 public void Main() 10 { 11 SubFactory sf=new SubFactory(); 12 Operator op=sf.CreateOperator(); 13 op.NumberA = 10; 14 op.NumberB = 5; 15 op.GetResult(); 16 } 17 } 18 public abstract class Operator 19 { 20 public double NumberA; 21 public double NumberB; 22 public virtual double GetResult() 23 { 24 return 0; 25 } 26 } 27 public class Add1:Operator 28 { 29 public override double GetResult() 30 { 31 return NumberA+NumberB; 32 } 33 } 34 public class Sub1:Operator 35 { 36 public override double GetResult() 37 { 38 return NumberA-NumberB; 39 } 40 } 41 42 interface IFactory 43 { 44 Operator CreateOperator(); 45 } 46 class AddFactory:IFactory 47 { 48 public Operator CreateOperator() 49 { 50 return new Add1(); 51 } 52 } 53 class SubFactory:IFactory 54 { 55 public Operator CreateOperator() 56 { 57 return new Sub1(); 58 } 59 } 60 }
六、原型模式設計模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 原型模式:從一個對象建立另外一個能夠定製的對象,並且不須要知道任何建立的細節 5 /// </summary> 6 class 原型模式 7 { 8 public void Main() 9 { 10 var s = new ConcretePrototype1("id"); 11 ((ProtoType) s).Idd();//訪問父類被隱藏的Idd方法 12 s.Idd();//默認訪問新類的Idd方法 13 var sClone=s.Clone(); 14 } 15 } 16 #region 例子1 17 abstract class ProtoType 18 { 19 private string Id; 20 protected ProtoType(string id) 21 { 22 this.Id = id; 23 } 24 public string Idd() 25 { 26 return Id; 27 } 28 public abstract ProtoType Clone(); 29 } 30 31 class ConcretePrototype1:ProtoType 32 { 33 public ConcretePrototype1(string id) : base(id) 34 { 35 } 36 public override ProtoType Clone() 37 { 38 return (ProtoType)this.MemberwiseClone();//淺表複製,值類型複製具體的值,引用類型複製引用! 39 } 40 public new string Idd() 41 { 42 return "ConcretePrototype1"; 43 } 44 } 45 #endregion 46 #region 例子2 深複製和淺複製 47 class WorkExperice:ICloneable 48 { 49 public string Name { get; set; } 50 public DateTime StarTime { get; set; } 51 public DateTime EndTime { get; set; } 52 public object Clone() 53 { 54 return new WorkExperice(){Name = this.Name,StarTime = StarTime,EndTime = EndTime};//深度複製 55 //return this.MemberwiseClone();若是屬性只有值類型,用這個方法就能夠實現淺表複製 56 } 57 } 58 59 #endregion 60 /// <summary> 61 /// 因爲Clone很是常見,因此.Net已經提供了這個Clone接口 62 /// </summary> 63 class MyClass:ICloneable 64 { 65 public object Clone() 66 { 67 return this.MemberwiseClone();//淺複製 68 } 69 } 70 }
七、模板模式多線程
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 模板模式:經過定義一個抽象類,抽象類裏的一個方法A內部調用了另外一個虛方法B,就能夠經過繼承這個抽象類,而後重寫這個虛方法,達到控制方法A的目的。最大程度上減小了類B的代碼重複量 5 /// 定義一個一個類的基本骨架,而後經過虛函數將部分差別性方法或者屬性在子類中從新定義,使得子類能夠不改變父類的基本骨架便可從新定義從父類繼承過來的一些方法。 6 /// 也就是說模板方法經過將不變的行爲搬移到父類中,去除了子類中的重複代碼,代碼複用程度較高。 7 /// </summary> 8 class _10_模板方法模式 9 { 10 public void Main() 11 { 12 var t = new TestPaper1(); 13 t.QuestionOneAnswer("26"); 14 t.QuestionOne(); 15 } 16 } 17 abstract class TestPaper 18 { 19 protected string Age; 20 public void QuestionOne() 21 { 22 Console.WriteLine("how old are you!"+QuestionOneAnswer(Age)); 23 } 24 public virtual string QuestionOneAnswer(string age) 25 { 26 return ""; 27 } 28 } 29 30 class TestPaper1:TestPaper 31 { 32 public override string QuestionOneAnswer(string age) 33 { 34 this.Age = age; 35 return age; 36 } 37 } 38 }
八、外觀模式ide
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 經過一個類對多個類進行集成,用戶只須要知道一個方法,就能夠調用多個被繼承類的功能 5 /// 對於老系統,若是要進行擴展修改能夠採用這種模式 6 /// </summary> 7 class _12_外觀模式 8 { 9 10 } 11 12 class Facade 13 { 14 public Writer1 Writer1 { get; set; } 15 public Writer2 Writer2 { get; set; } 16 public void Write() 17 { 18 Writer1.Write(); 19 Writer2.Write(); 20 } 21 } 22 23 interface IWriter 24 { 25 void Write(); 26 } 27 class Writer1:IWriter 28 { 29 public void Write() 30 { 31 Console.WriteLine("hello writer1"); 32 } 33 } 34 class Writer2:IWriter 35 { 36 public void Write() 37 { 38 Console.WriteLine("hello writer2"); 39 } 40 } 41 }
九、建造者模式函數
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 建造者模式:用於建立一些複雜的對象,這些對象內部構建間的建造順序較穩定,可是內部的構建過程是複雜變化的。 5 /// 建造者模式的好處就是使得建造代碼和具體的表示代碼分離,因爲建造者隱藏了該產品的具體實現,若是須要改變一個產品的內部表示,只須要從新再定義一個建造者就好了,或者在同一個建造者內部從新寫一個方法 6 /// 建造者Builder更像是一種對現有方法的有順序整合 7 /// </summary> 8 class _13_建造者模式 9 { 10 } 11 public abstract class Person 12 { 13 public abstract void BuildHead(); 14 public abstract void BuildBody(); 15 public abstract void BuildLag(); 16 } 17 public class TinPerson:Person 18 { 19 public override void BuildHead() 20 { 21 Console.WriteLine("TinHead"); 22 } 23 public override void BuildBody() 24 { 25 Console.WriteLine("TinBody"); 26 } 27 public override void BuildLag() 28 { 29 Console.WriteLine("TinLag"); 30 } 31 } 32 public class FatPerson:Person 33 { 34 public override void BuildHead() 35 { 36 throw new NotImplementedException(); 37 } 38 public override void BuildBody() 39 { 40 throw new NotImplementedException(); 41 } 42 public override void BuildLag() 43 { 44 throw new NotImplementedException(); 45 } 46 } 47 public class Builder 48 { 49 public Person Person {get; private set; } 50 public Builder(Person person) 51 { 52 this.Person = person; 53 } 54 public void Build(Person person) 55 { 56 person.BuildHead(); 57 Person.BuildBody(); 58 person.BuildLag(); 59 } 60 61 } 62 }
十、觀察者模式
namespace ConsoleApplication1 { /// <summary> /// 觀察者模式:定義了一種一對多的關係,讓多個觀察者對象同時監聽同一個主題對象,當這個主題對象狀態發生改變的時候,會通知全部的觀察者對象,使全部的觀察者對象執行特定操做 /// 參數傳遞儘可能依賴於接口和抽象類 /// </summary> class _14_觀察者模式 { public void Main() { ISubject boss=new Boss(); Observer observer=new Observer1("sss",boss); boss.Attach(observer); boss.Notify(); } } abstract class Observer { protected string Name; protected ISubject Subject; public abstract void Update(); } class Observer1:Observer { public Observer1(string name,ISubject subject)//一樣 參數也是接口傳遞,不依賴於具體的類 { this.Name = name; this.Subject = subject; } public override void Update() { Console.WriteLine(Name+Subject.Name+"在看股票呢"); } } interface ISubject { string Name { get; set; } List<Observer> Observers { get; set; } void Attach(Observer observer);//添加 void Detach(Observer observer);//剔除 void Notify();//通知 } class Boss:ISubject { public string Name { get; set; } public List<Observer> Observers { get; set; }//這裏須要添加繼承了Observe抽象類的對象,若是有的類沒有繼承Observe類,那麼建造者模式就失效了!這時能夠用委託來實現 public Boss() { this.Observers=new List<Observer>(); } public void Attach(Observer observer)//Attach函數的參數 都是接口傳遞,而不是具體的類,下降類間耦合 { Observers.Add(observer); } public void Detach(Observer observer) { Observers.Remove(observer); } public void Notify() { foreach (var observer in Observers) { observer.Update(); } } } }
十一、抽象工廠方法
1 namespace ConsoleApplication1 2 { 3 4 class _15_抽象工廠方法 5 { 6 public void Main() 7 { 8 IFactoryDatabase factory=new SqlServerFac(); 9 IDepartMent sqlServer=factory.GetInstance(); 10 sqlServer.Insert("helloworld!"); 11 } 12 } 13 interface IDepartMent 14 { 15 void Insert(string sql);//在數據庫中插入一條記錄 16 } 17 class SqlServer:IDepartMent 18 { 19 public void Insert(string sql) 20 { 21 Console.WriteLine("sqlServer執行sql插入語句!"); 22 } 23 } 24 25 class Access:IDepartMent 26 { 27 public void Insert(string sql) 28 { 29 Console.WriteLine("Access執行sql插入語句!"); 30 } 31 } 32 33 interface IFactoryDatabase 34 { 35 IDepartMent GetInstance(); 36 } 37 38 class SqlServerFac:IFactoryDatabase 39 { 40 public IDepartMent GetInstance() 41 { 42 return new SqlServer(); 43 } 44 } 45 46 class AccessFac:IFactoryDatabase 47 { 48 public IDepartMent GetInstance() 49 { 50 return new Access(); 51 } 52 } 53 }
十二、狀態模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 狀態模式:當一個對象的內在狀態改變時,容許改變其行爲,這個對象看起來像是改變了其類同樣 5 /// </summary> 6 class _16_狀態模式 7 { 8 9 } 10 }
1三、適配器模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 適配器模式:將一個類的接口轉換成客戶但願的另一個接口。適配器模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做 5 /// 須要的東西在面前,可是卻不能用,咱們能夠想辦法適配它 6 /// 系統的數據和行爲都正確,可是接口不符時,能夠考慮適配器模式。目的是使控制範圍外的一個原有對象與某個接口匹配。能夠起到複用一些現存類的做用。 7 /// 有點亡羊補牢的意思~~ 8 /// 應用場景:通常用在後期的系統維護階段,接口改變的狀況下使用!可是當咱們設計一個系統,調用第三方組件時,第三方的組件每每和咱們須要的接口是不一致的,此時就能夠用適配器模式 9 /// </summary> 10 class _17_適配器模式 11 { 12 } 13 class Target 14 { 15 public virtual void Request() 16 { 17 Console.WriteLine("客戶期待的接口"); 18 } 19 } 20 class Adaptee 21 { 22 public void SpecificQuest() 23 { 24 Console.WriteLine("須要適配的接口,即如今已經存在的一些功能"); 25 } 26 } 27 class Adapter:Target 28 { 29 //接口達到了Target的要求,同時調用了現有的Adaptee類功能 30 public override void Request() 31 { 32 new Adaptee().SpecificQuest(); 33 } 34 } 35 #region 示例2 36 37 /// <summary> 38 /// 球員類 39 /// </summary> 40 abstract class Player 41 { 42 protected string Name; 43 44 protected Player(string name) 45 { 46 this.Name = name; 47 } 48 public abstract void Attratk(); 49 public abstract void Defend(); 50 } 51 /// <summary> 52 /// 前鋒類 53 /// </summary> 54 class ForWard:Player 55 { 56 public ForWard(string name) : base(name) 57 { 58 this.Name = name; 59 } 60 public override void Attratk() 61 { 62 Console.WriteLine("ForWard Attrack"); 63 } 64 public override void Defend() 65 { 66 Console.WriteLine("ForWard Defend!"); 67 } 68 } 69 /// <summary> 70 /// 中國球員 71 /// </summary> 72 class ChinaPlayer 73 { 74 public string Name { get; set; } 75 public ChinaPlayer(string name) 76 { 77 Name = name; 78 } 79 public void ChineseStyleAttratk() 80 { 81 Console.WriteLine("中國球員式進攻!"); 82 } 83 public void ChineseStyleDefend() 84 { 85 Console.WriteLine("中國球員式防守"); 86 } 87 } 88 /// <summary> 89 /// 同化中國球員類ChinaPlayer,也就是複用ChinaPlayer 90 /// </summary> 91 class AssimilationChinesePlayer:Player 92 { 93 private ChinaPlayer Player; 94 public AssimilationChinesePlayer(string name) : base(name) 95 { 96 this.Name = name; 97 this.Player=new ChinaPlayer(name); 98 } 99 public override void Attratk()//接口保持了一致,同時內部調用了現有的ChinaPlayer 100 { 101 Player.ChineseStyleAttratk(); 102 } 103 public override void Defend() 104 { 105 Player.ChineseStyleDefend(); 106 } 107 } 108 #endregion 109 }
1四、備忘錄模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 備忘錄模式:在不破壞封裝性的前提下,捕獲一個對象的內部狀態,並在該對象以外進行保存,之後能夠將該對象恢復到原先保存的狀態了。 5 /// 6 /// </summary> 7 class _18_備忘錄模式 8 { 9 public void Main() 10 { 11 var role = new MainRole(){RoleBlood = 10,RoleMagic = 10,RoleName = "name"};//建立一個角色 12 var mementoManager = new MementoManager();//建立一個管理備忘錄的類 13 var roleMemento=role.SetMemento();//保存role角色的部分信息 14 mementoManager.Dictionary.Add(role.RoleName,roleMemento); 15 } 16 } 17 /// <summary> 18 /// 遊戲角色抽象類 19 /// </summary> 20 abstract class GameRole 21 { 22 protected string Name; 23 protected int Magic; 24 protected int Blood; 25 public abstract void Display();//展現信息接口 26 public abstract Memento SetMemento();//設置備忘錄 27 public abstract void ReCover(Memento memento);//根據備忘錄Memento恢復角色信息 28 29 } 30 /// <summary> 31 /// 備忘錄類 32 /// </summary> 33 class Memento 34 { 35 public string Name { get; set; } 36 public int Magic { get; set; } 37 public int Blood { get; set; } 38 } 39 class MainRole:GameRole 40 { 41 public string RoleName 42 { 43 get { return Name; } 44 set { Name = value; } 45 } 46 public int RoleMagic 47 { 48 get { return Magic; } 49 set { Magic = value; } 50 } 51 public int RoleBlood 52 { 53 get { return Blood; } 54 set { Blood = value; } 55 } 56 public override void Display() 57 { 58 Console.WriteLine(Name+Magic+Blood); 59 } 60 public override Memento SetMemento() 61 { 62 return new Memento(){Blood = this.Blood,Magic = this.Magic,Name = this.Name}; 63 } 64 public override void ReCover(Memento memento) 65 { 66 this.RoleBlood = memento.Blood; 67 this.RoleMagic = memento.Magic; 68 this.RoleName = memento.Name; 69 } 70 } 71 72 class MementoManager 73 { 74 /// <summary> 75 /// 存儲一個dictionary key用name表示 76 /// </summary> 77 public Dictionary<string,Memento> Dictionary=new Dictionary<string, Memento>(); 78 } 79 }
1五、組合模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 組合模式:可讓客戶一致的使用組合結構和單個對象 5 /// </summary> 6 class _19_組合模式 7 { 8 public void Main() 9 { 10 Company c=new ConcreteCompany("一個非葉子部門"); 11 Company d=new HrCompany("人事部門"); 12 c.Add(d); 13 c.LineOfDuty(); 14 c.Display(); 15 } 16 } 17 abstract class Company 18 { 19 protected string Name; 20 protected Company(string name) 21 { 22 this.Name = name; 23 } 24 public abstract void Add(Company a);//添加對象 25 public abstract void Remove(Company a);//刪除對象 26 public abstract void LineOfDuty();//履行職能(總體) 27 public abstract void Display();//展現 28 } 29 /// <summary> 30 /// 一個具體的Company 31 /// </summary> 32 class ConcreteCompany:Company 33 { 34 private List<Company> children=new List<Company>(); 35 public ConcreteCompany(string name):base(name) 36 {} 37 public override void Add(Company a) 38 { 39 children.Add(a); 40 } 41 public override void Remove(Company a) 42 { 43 children.Remove(a); 44 } 45 public override void LineOfDuty() 46 { 47 foreach (var company in children) 48 { 49 company.Display(); 50 } 51 } 52 public override void Display() 53 { 54 Console.WriteLine("This is ConcreteCompany display!"); 55 } 56 } 57 58 class HrCompany:Company 59 { 60 public HrCompany(string name):base(name) 61 { 62 this.Name = name; 63 } 64 public override void Add(Company a) 65 { 66 } 67 public override void Remove(Company a) 68 { 69 } 70 public override void LineOfDuty() 71 { 72 } 73 public override void Display() 74 { 75 Console.WriteLine("HR部門的職責是招人!"); 76 } 77 } 78 }
1六、單例模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 保證類的實例只有一個,而且提供一個全局訪問方法 5 /// </summary> 6 class _21_單例模式 7 { 8 } 9 #region 單線程下可行操做 10 class Singleton 11 { 12 private static Singleton instance; 13 private Singleton()//構造函數私有化,防止外界建立新對象 14 { } 15 public static Singleton GetInstance()//全局訪問instance方法 16 { 17 return instance ?? (instance = new Singleton());//多線程下可能new屢次 18 } 19 } 20 #endregion 21 #region 多線程可行操做 (lock鎖) 22 class Singleton1 23 { 24 private static Singleton1 instance; 25 private static readonly object myLock=new object(); 26 private Singleton1() 27 {} 28 public static Singleton1 GetInstance() 29 { 30 lock (myLock) 31 { 32 return instance ?? (instance = new Singleton1()); 33 } 34 } 35 } 36 #endregion 37 #region 多線程可行操做(雙重lock鎖) 38 39 class Singleton2 40 { 41 private static Singleton2 instance; 42 private static readonly object myLock=new object(); 43 private Singleton2() 44 {} 45 public static Singleton2 GetInstance() 46 { 47 if (instance == null) 48 { 49 lock (myLock) 50 { 51 if(instance==null) 52 instance=new Singleton2(); 53 } 54 } 55 return instance; 56 } 57 } 58 #endregion 59 #region 靜態初始化 60 public sealed class Singleton3//密封類,防止派生該類 61 { 62 private static readonly Singleton3 instance=new Singleton3(); 63 private Singleton3(){} 64 public static Singleton3 GetInstance() 65 { 66 return instance; 67 } 68 } 69 #endregion 70 }
1七、命令模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 一個類有一些具體的功能(烤肉者),將這些功能抽象出一個命令類,在經過每個繼承該命令類的具體類 調用 一個具體的功能,而後在定義一箇中間類(服務員),接收客戶端的命令請求,具體通知各個功能的全部者實現這些功能 5 /// </summary> 6 class _23_命令模式 7 { 8 public void Main() 9 { 10 Barbecuer boy=new Barbecuer(); 11 Command com1=new BakeChikenCommand(boy); 12 Command com2=new BakeChikenCommand(boy); 13 Waiter girl=new Waiter(); 14 girl.SetOrder(com1); 15 girl.SetOrder(com2); 16 girl.Execute(); 17 } 18 19 } 20 /// <summary> 21 /// 抽象命令類 22 /// </summary> 23 public abstract class Command 24 { 25 protected Barbecuer receiver; 26 protected Command(Barbecuer barbecuer) 27 { 28 this.receiver = barbecuer; 29 } 30 public abstract void ExecuteCommand(); 31 } 32 33 class BakeMuttonCommand:Command 34 { 35 public BakeMuttonCommand(Barbecuer barbecure) : base(barbecure) 36 { 37 this.receiver = barbecure; 38 } 39 public override void ExecuteCommand() 40 { 41 receiver.BakeMutton(); 42 } 43 } 44 45 class BakeChikenCommand:Command 46 { 47 public BakeChikenCommand(Barbecuer barbecure) : base(barbecure) 48 { 49 this.receiver = barbecure; 50 } 51 public override void ExecuteCommand() 52 { 53 receiver.BakeChicken(); 54 } 55 } 56 /// <summary> 57 /// 服務員類 能夠添加更多的功能函數 58 /// </summary> 59 public class Waiter 60 { 61 private IList<Command> commands=new List<Command>(); 62 public void SetOrder(Command command) 63 { 64 this.commands.Add(command); 65 } 66 public void Execute() 67 { 68 foreach (var command in commands) 69 { 70 command.ExecuteCommand(); 71 } 72 } 73 } 74 /// <summary> 75 /// 烤肉者 76 /// </summary> 77 public class Barbecuer 78 { 79 public void BakeMutton() 80 { 81 Console.WriteLine("烤肉"); 82 } 83 public void BakeChicken() 84 { 85 Console.WriteLine("烤雞翅"); 86 } 87 } 88 }
1八、職責鏈模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 使多個對象都有機會處理請求,將全部對象連成一個鏈,而且沿着這條鏈傳遞請求,直到有一個對象處理它爲止 5 /// </summary> 6 class _24_職責鏈模式 7 { 8 public void Main() 9 { 10 Manager m3=new Manager3(); 11 Manager m2 =new Manager2(m3); 12 Manager m1=new Manager1(m2); 13 m1.Handle("level2"); 14 } 15 } 16 17 abstract class Manager 18 { 19 protected Manager MyBoss; 20 public abstract void Handle(string oneThing); 21 } 22 /// <summary> 23 /// 級別爲1的Manager 24 /// </summary> 25 class Manager1:Manager 26 { 27 public Manager1(Manager boss) 28 { 29 MyBoss = boss; 30 } 31 //public void SetBoss(Manager boss)//代替構造函數初始化在 客戶端調用的時候更加靈活,能夠隨意的更改傳遞順序和請求處理節點 32 //{ 33 // this.MyBoss = boss; 34 //} 35 public override void Handle(string oneThing) 36 { 37 if (oneThing.Equals("level1")) 38 { 39 Console.WriteLine("I can handle the "+oneThing); 40 return; 41 } 42 Console.WriteLine("I can not handle the"+oneThing); 43 MyBoss.Handle(oneThing); 44 } 45 } 46 47 class Manager2:Manager 48 { 49 public Manager2(Manager boss) 50 { 51 MyBoss = boss; 52 } 53 public override void Handle(string oneThing) 54 { 55 if (oneThing.Equals("level2")) 56 { 57 Console.WriteLine("I can handle"+oneThing); 58 return; 59 } 60 Console.WriteLine("I can not Handle the"+oneThing); 61 MyBoss.Handle(oneThing); 62 } 63 } 64 65 class Manager3:Manager 66 { 67 public Manager3() 68 { 69 MyBoss = null; 70 } 71 public override void Handle(string oneThing) 72 { 73 if (oneThing.Equals("level3")) 74 { 75 Console.WriteLine("I can handle the "+oneThing+"Because i am CEO"); 76 return; 77 } 78 } 79 } 80 }
1九、中介者模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 用一箇中介者對象來封裝一系列的對象交互,中介者使各對象不須要顯示的相互引用,下降耦合,從而能夠獨立的改變他們之間的交互 5 /// </summary> 6 class _25_中介者模式 7 { 8 9 } 10 }
20、享元模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 經過共享實例對象,減小對象的建立,下降內存的損耗。 5 /// </summary> 6 class _26_享元模式 7 { 8 public void Main() 9 { 10 FlyWeight a=new FlyWeightA(); 11 FlyWeight b=new FlyWeightB(); 12 FlyWeightFactory fac=new FlyWeightFactory(); 13 fac.AddFlyWeight("a",a); 14 fac.AddFlyWeight("b",b); 15 var flyWeightA= fac.Get("a") as FlyWeightA;//經過fac工廠的get方法在其餘位置調用get方法 也會獲得同一個對象,減小了建立對象的開銷 16 flyWeightA.Operator(new Data());//經過客戶端傳遞外部數據進行處理 17 } 18 } 19 public class Data 20 { 21 public string str; 22 } 23 abstract class FlyWeight 24 { 25 public abstract void Operator(Data data); 26 } 27 class FlyWeightA:FlyWeight 28 { 29 public override void Operator(Data data) 30 { 31 //使用data裏的數據 32 Console.WriteLine("FlyWeightA"); 33 } 34 } 35 class FlyWeightB:FlyWeight 36 { 37 38 public override void Operator(Data data) 39 { 40 //使用data裏的數據 41 Console.WriteLine("FlyWeightB"); 42 } 43 } 44 45 class FlyWeightFactory 46 { 47 private Dictionary<string,FlyWeight> dic=new Dictionary<string, FlyWeight>(); 48 public void AddFlyWeight(string key,FlyWeight flyWeight) 49 { 50 if(!dic.Keys.Contains(key)) 51 dic.Add(key,flyWeight); 52 } 53 public FlyWeight Get(string key) 54 { 55 return dic.Keys.Contains(key) ? dic[key] : null; 56 } 57 } 58 }
2一、解釋器模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 5 /// </summary> 6 internal class _27_解釋器模式 7 { 8 } 9 10 /// <summary> 11 /// 抽象解釋器接口 12 /// </summary> 13 internal abstract class Expression 14 { 15 public abstract void Interpret(InterPretData data); 16 } 17 18 internal class NonExpression : Expression 19 { 20 public override void Interpret(InterPretData data) 21 { 22 Console.WriteLine("Non解釋處理data數據"); 23 } 24 } 25 26 internal class TerExpression : Expression 27 { 28 public override void Interpret(InterPretData data) 29 { 30 Console.WriteLine("Ter解釋處理data數據"); 31 } 32 } 33 }
2二、訪問者模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 一個做用於某對象結構中各元素的操做,它使你能夠在不改變各元素的類的前提下定義做用於這些元素的新操做 5 /// 利用雙分派技術 實現處理與數據機構的分離 6 /// </summary> 7 class _28_訪問者模式 8 { 9 public void Main() 10 { 11 //特色:Action和Human抽象類中的函數互爲各自的參數,可是要保證Action中的方法是穩定的。是兩個方法就是2個方法,萬一增長了雙性戀者,就不適用了 12 //若是要增長一種"結婚"狀態,只要重寫一個"結婚"類繼承自Action就能夠 13 } 14 } 15 /// <summary> 16 /// 狀態類(訪問者)(我的感受將Action當作一種數據更易理解) 增長訪問者很方便 17 /// </summary> 18 abstract class Action 19 { 20 public abstract void GetManConclusion(Human human); 21 public abstract void GetWomanConclusion(Human human); 22 } 23 abstract class Human 24 { 25 public abstract void Accept(Action action); 26 } 27 class Success:Action 28 { 29 public override void GetManConclusion(Human human) 30 { 31 Console.WriteLine("Man Success"); 32 } 33 public override void GetWomanConclusion(Human human) 34 { 35 Console.WriteLine("Woman Sucess"); 36 } 37 } 38 class Fail:Action 39 { 40 public override void GetManConclusion(Human human) 41 { 42 Console.WriteLine("Man Faile"); 43 } 44 public override void GetWomanConclusion(Human human) 45 { 46 Console.WriteLine("Woman Fail"); 47 } 48 } 49 class Man:Human 50 { 51 public override void Accept(Action action) 52 { 53 action.GetManConclusion(this); 54 } 55 } 56 57 class Woman:Human 58 { 59 public override void Accept(Action action) 60 { 61 action.GetWomanConclusion(this); 62 } 63 } 64 }