最近把《大话设计模式》重温了下(看完序才知道原来作者是也是博客园园友,这本书的最早博客版本在这里)。体会最深的就是面向接口编程的重要性,如何在自己的项目中进行抽象,合理的利用各种设计模式。怎么样尽可能屏蔽switch分支、各种if else判断。具体还得自己品味,体会!整理各个模式的Demo,让不是很了解设计模式的小伙伴迅速有一个大概印象,也方便以后自己查阅。据说点赞的伙伴最近都能加薪,双11前,单身的小伙伴能顺利脱单~~pull Git
1、简单工厂模式:
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 }
2、策略模式
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 }
3、装饰模式
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;//1、将可能需要的一些别的类的定义在自己的类中, 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)//2、通过动态添加特定的实现了接口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 }
4、代理模式
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 }
5、工厂方法模式
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 }
6、原型模式
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 }
7、模板模式
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 }
8、外观模式
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 }
9、建造者模式
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 }
10、观察者模式
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(); } } } }
11、抽象工厂方法
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 }
12、状态模式
1 namespace ConsoleApplication1 2 { 3 /// <summary> 4 /// 状态模式:当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类一样 5 /// </summary> 6 class _16_状态模式 7 { 8 9 } 10 }
13、适配器模式
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 }
14、备忘录模式
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 }
15、组合模式
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 }
16、单例模式
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 }
17、命令模式
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 }
18、职责链模式
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 }
19、中介者模式
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 }
21、解释器模式
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 }
22、访问者模式
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 }