设计模式汇总(含示例代码)_第1页
设计模式汇总(含示例代码)_第2页
设计模式汇总(含示例代码)_第3页
设计模式汇总(含示例代码)_第4页
设计模式汇总(含示例代码)_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、设计模式(Design Pattern)设计模式主要分三个类型:创建型、结构型和行为型。 创建型: 一、单例模式(Singleton):保证一个类只有一个实例,并提供一个访问它的全局访问点 二、抽象工厂(Abstract Factory):提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。 三、工厂方法(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。 四、建造模式(Builder):将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。五、原型模式(Prot

2、otype):用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。 行为型: 六、迭代器模式(Iterator):提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。七、观察者模式(Observer):定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。 八、模板方法(Template Method):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,Template Method使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。 九、命令模式(Command):将一个请求封装为一个对象,从而使

3、你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。 十、状态模式(State):允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。 十一、策略模式(Strategy):定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。 十二、职责链模式(Chain of Responsibility):使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系 十三、中介者模式(Mediator):用一个中介对象封装一些列的对象交互。十四、访问者模式(Visitor):表示一个作用于某对象结构中

4、的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。 十五、解释器模式(Interpreter):给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 十六、备忘录模式(Memento):在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。结构型: 十七、组合模式(Composite):将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。 十八、外观模式(Facade):为子系统中的一组接口提供一致的界面,facade提供了一个高层接口,这个接口使得

5、子系统更容易使用。 十九、代理模式(Proxy):为其他对象提供一种代理以控制对这个对象的访问 二十、适配器模式(Adapter):将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。 二十一、装饰模式(Decorator):动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。 二十二、桥模式(Bridge):将抽象部分与它的实现部分相分离,使他们可以独立的变化。 二十三、享元模式(Flyweight)一、 单例模式:单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个

6、实例。这个类称为单例类。单例模式特点:单例类只能有一个实例。单例类必须自己创建自己的唯一实例。单例类必须给所有其他对象提供这一实例。 示例代码一:public class Singletonprivate static Singleton _instance = null;private static object _lock = new object();private Singleton() public static Singleton GetInstance()if(_instance = null)lock(_lock) /线程安全 if(instance=null) instanc

7、e=new Singleton(); return _instance;先看内层的if语句块,使用这个语句块时,先进行加锁操作,保证只有一个线程可以访问该语句块,进而保证只创建了一个实例。再看外层的if语句块,这使得每个线程欲获取实例时不必每次都得加锁,因为只有实例为空时(即需要创建一个实例),才需加锁创建,若果已存在一个实例,就直接返回该实例,节省了性能开销。 示例代码二:public sealed class Singleton private static readonly Singleton instance = new Singleton(); private Singleton()

8、 public static Singleton GetInstance() return instance; 上面使用的readonly关键字可以跟static一起使用,用于指定该常量是类别级的,它的初始化交由静态构造函数实现,并可以在运行时编译。在这种模式下,无需自己解决线程安全性问题,CLR会给我们解决。二、 多例模式所谓多例模式,实际上就是单例模式的自然推广,单例类一般情况下只可以有一个实例,但单例类也可以推广到允许有限个实例,这种模式就是多例模式。多例模式有以下特点:多例类可以有多个实例。多例类必须自己创建、管理自己的实例,并向外界提供自己的实例。多例类分为有上限多例类与无上限多例类

9、。 示例代码:public class Multitonprivate static Multiton instance1 = null;private static Multiton instance2 = null;private Multiton() public static Multiton GetInstance(int whichOne)if(whichOne = 1)if(instance1 = null)instance1 = new Multiton();return instance1;elseif(instance2 = null)instance2 = new Mul

10、titon(); return instance2;多例类的实例数目不需要有上限,实例数目没有上限的多例模式就叫做无上限多例模式。由于没有上限的多例类对实例的数目是没有限制的,因此,虽然这种多例模式是单例模式的推广,但是这种多例类并不一定能够回到单例类。一般采用聚集管理所有的实例。三、 抽象工厂示例代码:public interface IFruit public class Orange : IFruit public Orange() Console.WriteLine(An orange is got!); public class Apple : IFruit public Apple

11、() Console.WriteLine(An apple is got!); public class FruitFactory public IFruit MakeFruit(string Name) IFruit MyFruit = null; try Type type = Type.GetType(Name, true); MyFruit = (IFruit)Activator.CreateInstance(type); catch (TypeLoadException e) Console.WriteLine(I dont know this kind of fruit,excep

12、tion caught - 0, e.Message); return MyFruit; 利用反射的好处:增加新的产品的时候,不需要修改客户代码,同时工厂的代码也不需要修改。四、 工厂方法工厂方法模式(Factory Method Pattern)是类的创建模式,其用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。工厂模式的角色与结构:抽象工厂(Creator)角色:是工厂 方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。具体工厂(ConcreteCreator)角色:这是实现抽象工厂接口的具体工厂类,包含与应用程序密切相关的逻辑,并且受到应用程

13、序调用以创建产品对象。在示例中有两个这样的角色:BulbCreator与TubeCreator。抽象产品(Product)角色:工厂方法模式所创建的对象的超类型,也就是产品对象的共同父类或共同拥有的接口。在示例中这个角色是Light。具体产品(ConcreteProduct)角色:这个角色实现了抽象产品角色所定义的接口。某具体产品有专门的具体工厂创建,它们之间往往一一对应。示例代码:public abstract class Light /抽象产品(Product)角色 public abstract void TurnOn(); public abstract void TurnOff();

14、 public class BulbLight : Light /具体产品(Concrete Product)角色 public override void TurnOn() Console.WriteLine(Bulb Light is Turned on); public override void TurnOff() Console.WriteLine(Bulb Light is Turned off); public class TubeLight : Light /具体产品(Concrete Product)角色 public override void TurnOn() Conso

15、le.WriteLine(Tube Light is Turned on); public override void TurnOff() Console.WriteLine(Tube Light is Turned off); public abstract class Creator /抽象工厂(Creator)角色 public abstract Light Create(); public class BulbCreator : Creator /具体工厂(Concrete Creator)角色 public override Light Create() return new Bul

16、bLight(); public class TubeCreator : Creator /具体工厂(Concrete Creator)角色 public override Light Create() return new TubeLight(); public class Client public static void Main() Creator c1 = new BulbCreator(); Creator c2 = new TubeCreator(); Light l1 = c1. Create(); Light l2 = c2. Create(); l1.TurnOn(); l

17、1.TurnOff(); l2.TurnOn(); l2.TurnOff(); 五、 建造模式意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。示例代码:namespace BuilderExemple class ComputerFactory /* * ComputerFactory是建造者模式的指导者。指导者做的是稳定的建造工作。 * 假设它就是一个技术人员,他只是在做按照固定的流程,把配件组装成计算机的重复劳动工作。 * 他不知道他现在组装的是一台游戏电脑还是一台办公用电脑,他也不知道他往主板上安装的内存是1G还是2G的。 */ public void Bui

18、ldComputer(ComputerBuilder cb) Console.WriteLine(); Console.WriteLine(Start Building + cb.Name); cb.SetupMainboard(); cb.SetupCpu(); Console.WriteLine(Build + cb.Name + Completed); Console.WriteLine(); abstract class ComputerBuilder /* * ComputerBuilder是抽象建造者角色。 * 它主要是用来定义两种接口,一种接口用于规范产品的各个部分的组成。比如,

19、这里就规定了组装一台电脑所需要的工序。 * 第二种接口用于返回建造后的产品,在这里我们没有定义抽象方法,反正建造出来的总是电脑。 */ public ComputerBuilder() computer = new Computer(); protected string name; public string Name get return name; set name = value; protected Computer computer; public Computer Computer get return computer; set computer = value; public

20、 abstract void SetupMainboard(); public abstract void SetupCpu(); class OfficeComputerBuilder : ComputerBuilder /* * OfficeComputerBuilder和GameComputerBuilder是具体的建造者。* 他的工作就是实现各建造步骤的接口,以及实现返回产品的接口,在这里后者省略了 */ public OfficeComputerBuilder() name = OfficeComputer; public override void SetupMainboard()

21、 computer.Mainboard = Abit升技LG-95C 主板(Intel 945GC芯片组/LGA 775/1066MHz) ; public override void SetupCpu() computer.Cpu = Intel 英特尔赛扬D 336 (2.8GHz/LGA 775/256K/533MHz) ; class GameComputerBuilder : ComputerBuilder /* * OfficeComputerBuilder和GameComputerBuilder是具体的建造者。* 他的工作就是实现各建造步骤的接口,以及实现返回产品的接口,在这里后

22、者省略了 */ public GameComputerBuilder() name = GameComputer; public override void SetupMainboard() computer.Mainboard = GIGABYTE技嘉GA-965P-DS3 3.3 主板(INTEL P965 东莞产); public override void SetupCpu() computer.Cpu = Intel 英特尔酷睿E4400 (2.0GHz/LGA 775/2M/800MHz)盒装; class Computer /* * Computer就是建造出来的复杂产品。 *

23、在代码中,我们的各种建造步骤都是为创建产品中的各种配件服务的,Computer定义了一个相对具体的产品 * 在应用中可以把这个产品进行比较高度的抽象,使得不同的具体建造者甚至可以建造出完全不同的产品。 */ private string mainboard; public string Mainboard get return mainboard; set mainboard = value; private string cpu; public string Cpu get return cpu; set cpu = value; public void ShowSystemInfo() C

24、onsole.WriteLine(=SystemInfo=); Console.WriteLine(CPU: + cpu); Console.WriteLine(MainBoard: + mainboard); class Program static void Main(string args) /* * 看看客户端的代码,用户先是选择了一个具体的Builder。 * 用户应该很明确它需要游戏电脑还是办公电脑,但是它可以对电脑一无所知,由销售人员给出一个合理的配置单。 * 然后用户让ComputerFactory去为它组装这个电脑。 * 组装完成后ComputerFactory开机,给用户验

25、收电脑的配置是否正确。 * * 你或许觉得ComputerBuilder和是抽象工厂模式中的抽象工厂角色差不多,GameComputerBuilder又像是具体工厂。 * 其实,建造者模式和抽象工厂模式的侧重点不同, * 前者强调一个组装的概念,一个复杂对象由多个零件组装而成并且组装是按照一定的标准射顺序进行的, * 而后者强调的是创建一系列产品。* 建造者模式适用于组装一台电脑,而抽象工厂模式适用于提供用户笔记本电脑、台式电脑和掌上电脑的产品系列。 */ ComputerFactory factory = new ComputerFactory(); ComputerBuilder offi

26、ce = new OfficeComputerBuilder(); factory.BuildComputer(office); office.Computer.ShowSystemInfo(); ComputerBuilder game = new GameComputerBuilder(); factory.BuildComputer(game); game.Computer.ShowSystemInfo(); 何时采用从代码角度来说, 如果你希望分离复杂类型构建规则和类型内部组成,或者希望把相同的构建过程用于构建不同类型的时候可以考虑使用建造者模式。从应用角度来说, 如果你希望解耦产品的

27、创建过程和产品的具体配件,或者你希望为所有产品的创建复用一套稳定并且复杂的逻辑的时候可以考虑使用建造者模式。实现要点对象的构建过程由指导者完成,具体的组成由具体建造者完成,表示与构建分离。建造者和指导者是建造者模式的关键点,如果进行合并或省略就可能会转变到模版方法模式。如果对象的建造步骤是简单的,并且产品拥有一致的接口可以转而使用工厂模式。六、 原型模式意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。何时采用:从代码角度来说, 如果你希望运行时指定具体类(比如是使用Footman作为敌人还是使用其它),或者你希望避免创建对象时的初始化过程(如果这个过程占用的时间和资源都非

28、常多),或者是希望避免使用工厂方法来实现多态的时候,可以考虑原型模式。从应用角度来说, 如果你创建的对象是多变化、多等级的产品,或者产品的创建过程非常耗时的时候(比如,有一定的计算量,或者对象创建时需要从网络或数据库中获取一定的数据),或者想把产品的创建独立出去,不想了解产品创建细节的时候可以考虑使用。不得不说,原型模式给了我们多一种创建对象,并且不依赖具体对象的选择。实现要点:.NET中使用Object的MemberwiseClone()方法来实现浅拷贝,通过序列化和反序列化实现深拷贝,后者代价比较大,选择何时的拷贝方式。原型模式同样需要抽象类型和具体类型,通过相对稳定的抽象类型来减少或避免

29、客户端的修改可能性。注意事项:注意选择深拷贝和浅拷贝。拷贝原型并进行修改意味着原型需要公开更多的数据,对已有系统实现原型模式可能修改的代价比较大。示例代码:namespace PrototypeExample class Program static void Main(string args) GameScene gs = new GameScene(); Enemy enemyPrototype = new FootMan(5, 4, new Location(100, 200); List enemyGroup = gs.CreateEnemyGroup(enemyPrototype);

30、 foreach (FootMan ft in enemyGroup) ft.ShowInfo(); ft.FootmanAttack(); class GameScene /调用方,原型模式通过对原型进行克隆来替代无数子类,因此也就减少了调用方和具体类型产生依赖的程序 public List CreateEnemyGroup(Enemy enemyPrototype) List enemyGroup = new List(); Enemy e1 = enemyPrototype.Clone(true); e1.Location.x = enemyPrototype.Location.x -

31、10; Enemy e2 = enemyPrototype.Clone(true); e2.Location.x = enemyPrototype.Location.x + 10; Enemy elite = enemyPrototype.Clone(true); elite.Power = enemyPrototype.Power * 2; elite.Speed = enemyPrototype.Speed * 2; elite.Location.x = enemyPrototype.Location.x; elite.Location.y = enemyPrototype.Locatio

32、n.y + 10; enemyGroup.Add(e1); enemyGroup.Add(e2); enemyGroup.Add(elite); return enemyGroup; Serializable class Location public int x; public int y; public Location(int x, int y) this.x = x; this.y = y; Serializable abstract class Enemy /抽象原型,它有两个用途,一是定义了原型的一些抽象内容,二是定义了原型模式必须的拷贝方法 protected Location

33、location; public Location Location get return location; set location = value; protected int power; public int Power get return power; set power = value; protected int speed; public int Speed get return speed; set speed = value; public abstract Enemy Clone(bool isDeepCopy); public abstract void ShowI

34、nfo(); public Enemy(int power, int speed, Location location) Thread.Sleep(1000); / Construct method is assumed to be a high calc work. this.power = power; this.speed = speed; this.location = location; /具体实现类 Serializable class FootMan : Enemy private string model; public FootMan(int power, int speed

35、, Location location) : base(power, speed, location) model = footman; public override void ShowInfo() Console.WriteLine(model:0 power:1 speed:2 location:(3,4), model, power, speed, location.x, location.y); public override Enemy Clone(bool isDeepCopy) /.NET中使用Object的MemberwiseClone()方法来实现浅拷贝,通过序列化和反序列

36、化实现深拷贝,后者代价比较大 FootMan footman; if (isDeepCopy) MemoryStream memoryStream = new MemoryStream(); BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(memoryStream, this); memoryStream.Position = 0; footman = (FootMan)formatter.Deserialize(memoryStream); else footman = (FootMan)this.

37、MemberwiseClone(); return footman; public void FootmanAttack() Console.WriteLine(FootmanAttack); 七、 迭代器模式意图:提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。要点:首先要实现IEnumerable接口,实现的GetEnumerator方法要返回一个IEnumerator的类型的集合。yield return关键字能够支持迭代的简化,动态生成迭代的类型。迭代抽象:访问一个聚合对象的内容而无需暴露它的内部表示。迭代多态:为遍历不同的集合结构提供一个统一的接口,从而支持

38、同样的算法在不同的集合结构上进行操作。算法应该是独立的,写的时候应该尽量操作接口。八、 观察者模式原理:把观察目标理解为主动方、发布方、主体等;把观察者理解为被动方、订阅方、观察器等。目标是整个行为链的源头,其它观察者都依赖于它的变化而作出响应。要点:把观察者模式的参与者都描述为派生自模型及观察者二个抽象基类的类。模型规划了事件,而观察者则规划了订阅及行为。模型需要做的只是声明委托以及声明委托类型的事件。当然,还可以附加上封装了触发委托事件的方法。所有派生自模型的类都是具体目标,它们所要做的只是在适当的场合触发事件。(即发出“通知”)。在观察者基类中,通过构造器将抽象的响应方法注册(订阅)于委

39、托事件中。所有派生自观察者基类的类都是具体观察者。因为订阅行为已经在抽象基类完成,具体观察者需要做的只是通过覆盖观察者基类的方法去定义具体需要响应的行为,和通过构造器把需要观察的具体目标传递给基类构造器。优点:通过对模型与观察者基类的分析可知,委托与事件的机制几乎消除了这两个模块之间的耦合,灵活性提高了很多。如果需要增加观察者,则只需要覆盖基类抽象方法及把观察目标传递给基类。示例代码:/ / 在Observer Pattern(观察者模式)中,此类作为所有Subject(目标)的抽象基类 / 所有要充当Subject的类(在此事例中为猫)都继承于此类. / 我们说此类作为模型,用于规划目标(即

40、发布方)所产生的事件,及提供触发 / 事件的方法. / 此抽象类无抽象方法,主要是为了不能实例化该类对象,确保模式完整性. / 具体实施: / 1.声明委托 / 2.声明委托类型事件 / 3.提供触发事件的方法 / public abstract class Subject / / 声明一个委托,用于代理一系列无返回及不带参的自定义方法 / public delegate void SubEventHandler(); / / 声明一个绑定于上行所定义的委托的事件 / public event SubEventHandler SubEvent; / / 封装了触发事件的方法,主要为了规范化及安全性,除观察者基类外,其派生类不直接触发委托事件 / protected void Notify() if (this.SubEvent != null) this.SubEvent(); / / 此类为观察者模式中的具体目标(即具体发布方),其继承于模型 / public class Cat : Subject / / 定义一种行为 / public void Cry() Console.WriteLine(cat cryed.); /调用了触发委托事件的方法,通知委托开始执行观察者已订阅的方法 this.Notify(); / / 在Observer Pattern(观

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论