二十三种设计模式类图
- 格式:doc
- 大小:231.50 KB
- 文档页数:17
二十三种设计模式0 引言谈到设计模式,绝对应该一起来说说重构。
重构给我们带来了什么?除了作为对遗留代码的改进的方法,另一大意义在于,可以让我们在写程序的时候可以不需事先考虑太多的代码组织问题,当然这其中也包括了应用模式的问题。
尽管大多数开发者都已经养成了写代码前先从设计开始的习惯,但是,这种程度的设计,涉及到到大局、到总体架构、到主要的模块划分我觉得就够了。
换句话说,这时就能写代码了。
这就得益于重构的思想了。
如果没有重构的思想,有希望获得非常高质量的代码,我们就不得不在开始写代码前考虑更多其实并非非常稳定的代码组织及设计模式的应用问题,那开发效率当然就大打折扣了。
在重构和设计模式的合理应用之下,我们可以相对较早的开始写代码,并在功能尽早实现的同时,不断地通过重构和模式来改善我们的代码质量。
所以,下面的章节中,在谈模式的同时,我也会谈谈关于常用的这些模式的重构成本的理解。
重构成本越高意味着,在遇到类似的问题情形的时候,我们更应该提前考虑应用对应的设计模式,而重构成本比较低则说明,类似的情形下,完全可以先怎么方便,怎么快怎么写,哪怕代码不是很优雅也没关系,回头再重构也很容易。
1 创建型1.1FactoryMethod思想:Factory Method的主要思想是使一个类的实例化延迟到其子类。
场景:典型的应用场景如:在某个系统开发的较早阶段,有某些类的实例化过程,实例化方式可能还不是很确定,或者实际实例化的对象(可能是需要对象的某个子类中的一个)不确定,或者比较容易变化。
此时,如果直接将实例化过程写在某个函数中,那么一般就是if-else或select-case代码。
如果,候选项的数目较少、类型基本确定,那么这样的if-else还是可以接受的,一旦情形变得复杂、不确定性增加,更甚至包含这个构造过程的函数所在的类包含几个甚至更多类似的函数时,这样的if-else代码就会变得比较不那么容易维护了。
此时,应用本模式,可以将这种复杂情形隔离开,即将这类不确定的对象的实例化过程延迟到子类。
设计模式(1、创造型2、结构型、3⾏为型)
设计模式六⼤原则:单⼀职责、⾥⽒替换、依赖倒置、最⼩接⼝、迪⽶特、开闭
这些只能叫原则,叫建议,没有实际的招数
23种设计模式,就是具体的招数,他们可以分成三⼤类。
1、创造型2、结构型、3⾏为型。
创造型设计模式关注对象的创建。
就是咱们的new().单例模式、原型模式、⼯⼚⽅法、抽象⼯⼚、建造者模式
结构型设计模式关注类与类之间的关系。
继承或者组合。
说⽩了就是包⼀层。
适配器模式、代理模式、装饰器模式、外观模式、组合模式、桥接模式、享元模式
⾏为型设计模式关注对象和⾏为的分离。
流程⽤的多些,说⽩了就是把逻辑丢出去,具体逻辑上端⾃⼰实现,下端只做流程。
模板⽅法设计模式、观察者模式、责任链模式
23种设计模式是前辈们总结出来的。
是为了解决具体的⼀类问题总结出来的,我遇到好多⼩伙伴觉得设计模式很⽜逼。
其实没那么伟⼤。
某种设计模式解决⼀类问题也会带来另⼀种问题。
所以合理应⽤才是最好的。
所以,有些设计模式不是必须应⽤进去。
不必强求。
我也是后来者,对前辈们总结的⼀些理解,学习和应⽤。
希望也能帮到看到这⾥的求学者。
下⾯⼏章。
都是对这23种设计模式的解读,不过我是总结成三⼤类。
尽量⽤最普通的话去阐述。
设计模式主要分三个类型:创建型、结构型和行为型。
其中创建型有:一、Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点二、Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。
三、Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。
四、Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。
五、Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。
行为型有:六、Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。
七、Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。
八、Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。
九、Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。
十、State,状态模式:允许对象在其内部状态改变时改变他的行为。
对象看起来似乎改变了他的类。
十一、Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。
十二、China of Responsibility,职责链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系十三、Mediator,中介者模式:用一个中介对象封装一些列的对象交互。
C#23种设计模式汇总创建型模式在⼯⼚⽅法模式中,⼯⼚⽅法⽤来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这⼀细节。
⼯⼚⽅法模式的核⼼是⼀个抽象⼯⼚类,各种具体⼯⼚类通过抽象⼯⼚类将⼯⼚⽅法继承下来。
如此使得客户可以只关⼼抽象产品和抽象⼯⼚,完全不⽤理会返回的是哪⼀种具体产品,也不⽤关系它是如何被具体⼯⼚创建的。
抽象⼯⼚模式的主要优点是隔离了具体类的⽣成,使得客户不需要知道什么被创建了。
犹豫这种隔离,更换⼀个具体⼯⼚就变得相对容易。
所有的具体⼯⼚都实现了抽象⼯⼚中定义的那些公共接⼝,因此只需改变具体⼯⼚的实例,就可以在某种程度上改变这个软件的系统的⾏为。
另外,应⽤抽象⼯⼚模式符合GRASP纯虚构的模式,可以实现⾼内聚低耦合的设计⽬的,因此抽象⼯⼚模式得到了⼴泛应⽤。
建造者模式将⼀个复杂对象的⽣成责任作了很好的分配。
它把构造过程放在指挥者的⽅法中,把装配过程放到具体建造者类中。
建造者模式的产品之间都有共通点,但有时候,产品之间的差异性很⼤,这就需要借助⼯⼚⽅法模式或抽象⼯⼚模式。
另外,如果产品的内部变化复杂,Builder的每⼀个⼦类都需要对应到不同的产品去做构建的动作、⽅法,这就需要定义很多个具体建造类来实现这种变化。
Singleton单例模式为⼀个⾯向对象的应⽤程序提供了对象唯⼀的访问点,不管它实现何种功能,此种模式都为设计及开发团队提供了共享的概念。
然⽽,Singleton对象类派⽣⼦类就有很⼤的困难,只有在⽗类没有被实例化时才可以实现。
值得注意的是,有些对象不可以做成Singleton,⽐如.net的数据库链接对象(Connection),整个应⽤程序同享⼀个Connection对象会出现连接池溢出错误。
另外,.net提供了⾃动废物回收的技术,因此,如果实例化的对象长时间不被利⽤,系统会认为它是废物,⾃动消灭它并回收它的资源,下次利⽤时⼜会重新实例化,这种情况下应注意其状态的丢失。
面向对象设计的23个设计模式详解面向对象设计是一种广泛应用于软件开发的思想,其核心在于将数据和操作封装在一起形成对象,并通过各种方式进行交互和组合,从而实现复杂的功能。
在这一过程中,设计模式起到了非常重要的作用,可以有效地提高代码的可读性、可维护性和可扩展性。
本文将对23种常见的设计模式进行详解。
一、创建型模式1.简单工厂模式简单工厂模式属于创建型模式,其目的是提供一个工厂类,使得创建对象的过程更加简单。
在这种模式中,使用者只需要提供所需对象的参数,而无需关心对象的具体实现细节。
简单工厂模式适合于对象创建过程较为简单的情况。
2.工厂方法模式工厂方法模式是简单工厂模式的进一步扩展,其核心在于将工厂类进行接口抽象化,使得不同的工厂类可以创建不同的对象实例。
工厂方法模式适合于对象创建过程较为复杂的情况。
它可以为工厂类添加新的产品类型,而不会影响原有的代码。
3.抽象工厂模式抽象工厂模式是工厂方法模式的进一步扩展,其目的是提供一个可以创建一系列相关或者独立的对象的接口。
在抽象工厂模式中,使用者只需要关心所需对象组合的类型,而无需关注对象的具体实现过程。
4.建造者模式建造者模式也是一种创建型模式,其目的在于将复杂对象分解为多个简单的部分,并将其组装起来形成复杂对象实例。
在建造者模式中,使用者只需要关注所需对象以及它们的组合方式,而无需关心对象的具体实现过程。
5.原型模式原型模式是一种基于克隆的创建型模式,其核心在于通过复制现有的对象实例来创建新的对象。
在原型模式中,对象实例的创建过程与对象所包含的状态密切相关。
原型模式适合于创建复杂对象实例,且这些对象实例之间是相对独立的情况。
二、结构型模式6.适配器模式适配器模式是一种结构型模式,其目的在于将一个类的接口转换为另一个类所能使用的接口。
在适配器模式中,使用者可以通过不同的适配器实现对象之间的互相调用。
7.桥接模式桥接模式是一种结构型模式,其目的在于将抽象部分与实现部分相互分离,从而使得两者可以独立变化。
23种设计模式详解设计模式是指面向对象编程中,经过多次验证、被广泛接受的代码实现方法。
这些设计模式可以帮助开发者更快地解决问题,提高代码的可读性、可维护性、可扩展性。
目前,常用的设计模式有23种。
下面,我们来详细介绍一下这23种设计模式。
1. 单例模式(Singleton)单例模式是一种只允许生成一个实例的模式。
在实例化对象时,单例模式的生成过程比较特殊,需要先判断该类是否已经实例化过,如果已经实例化,则直接返回已有的实例对象,否则再进行实例化。
2. 工厂模式(Factory)工厂模式是一种生产对象实例的设计模式。
它将对象实例的生成过程封装在一个工厂类中,客户端需要对象时,只需要调用工厂类中对应的方法即可。
3. 抽象工厂模式(Abstract Factory)抽象工厂模式是一种扩展了工厂模式的模式。
它可以生成一系列相关或相互依赖的对象实例。
具体实现时,通常需要定义一个抽象工厂类和一些具体工厂类,来生产各种相关的对象实例。
4. 建造者模式(Builder)建造者模式是一种用于构建复杂对象的模式。
它将一个复杂对象的构建过程分解成多个简单的步骤,然后通过一个指挥者来管理这些步骤的执行,最终构建出一个复杂的对象。
5. 原型模式(Prototype)原型模式是一种通过复制已有对象来创建新对象的模式。
一般来说,系统中的对象包含大量相同或相似的部分,通过复制对象可以帮助我们节省生成对象的时间和资源。
6. 适配器模式(Adapter)适配器模式是一种将不兼容接口转换为兼容接口的模式。
具体实现时,需要定义一个适配器类,该类实现了客户端所期望的接口,而且还包装了原有不兼容的接口,使其能够兼容客户端期望的接口。
7. 桥接模式(Bridge)桥接模式是一种将抽象部分与其实现部分分离开来的模式。
具体实现时,需要定义抽象部分和实现部分的接口,然后定义一个桥接类,将抽象部分和实现部分联系起来。
8. 组合模式(Composite)组合模式是一种将具有相同属性和方法的对象组合成树形结构的模式。
Factory模式1.简单工厂模式,又称为静态工厂模式2.工厂方法模式3. 抽象工厂模式抽象工厂模式与工厂方法模式的最大区别在于,工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则需要面对多个产品等级结构。
Builder模式Builder模式利用一个Director对象和ConcreteBuilder对象一个一个地建造出所有的零件,从而建造出完整的Product。
Builder模式将产品的结构和产品的零件建造过程对客户端隐藏起来,把对建造过程进行指挥的责任和具体的建造者零件的责任分割开来,达到责任划分和封装的目的。
使用Builder模式的场合:●需要生成的产品对象有复杂的内部结构。
每一个内部成分本身可以是对象,也可以紧紧是产品对象的一个组成部分。
●需要生成的产品对象的属性相互以来。
Builder模式可以强制实行一种分步骤进行的建造过程,因此,如果产品对象的一个属性必须在另一个属性被赋值之后才可以被赋值,使用建造模式便是一个很好的设计思想。
●在对象创建过程中会使用到系统中的其他一些对象,这些对象在产品对象的创建过程中不易得到。
Prototype模式通过给出一个原型对象来指明所要创建的对象的类型,然后用赋值这个原型对象的办法创建出更多同类型的对象。
CloneableAdapter模式把一个类的接口变换成客户端所期待的另一种接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作,也就是说把接口不同而功能相同或相近的多个接口加以转换。
1.类的Adapter模式的结构2.对象的Adapter模式的结构注意两种结构的区别:主要就是Adaptee和Adapter的关系,一个为继承关系,一个为依赖关系。
使用Adapter模式的场合:●系统需要使用现在的类,而此类的接口不符合系统的需要。
●想要建立一个可以重复使用的类,用语与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。
这些源类不一定有很复杂的接口。
六大设计原则和23种设计模式
设计原则是设计模式的基础,六大设计原则是SOLID原则和DRY原则。
SOLID是单一职责原则(Single Responsibility Principle,SRP)、开闭原则(Open Closed Principle,OCP)、里氏替换原则(Liskov Substitution Principle,LSP)、接口隔离原则(Interface Segregation Principle,ISP)和依赖反转原则(Dependency Inversion Principle,DIP)。
DRY原则是不要重复自己(Don't Repeat Yourself)。
设计模式是软件设计中常用的解决问题的模式,常见的23种设计模式包括:
1. 创建型模式,工厂方法模式、抽象工厂模式、建造者模式、原型模式、单例模式。
2. 结构型模式,适配器模式、桥接模式、组合模式、装饰者模式、外观模式、享元模式、代理模式。
3. 行为型模式,责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模
式、模板方法模式、访问者模式。
这些设计原则和设计模式在软件开发中起着重要的作用。
设计原则有助于编写具有良好结构和可维护性的代码,而设计模式则提供了解决特定问题的经过验证的解决方案。
通过遵循这些原则和模式,开发人员可以编写出高质量、可扩展和易于维护的软件系统。
同时,这些原则和模式也有助于促进团队之间的沟通和协作,使得软件开发过程更加高效和可靠。
软件设计常见的23种设计模式 在现代软件开发当中,设计模式起到⾄关重要的作⽤。
尤其是⾃从⾯向对象的语⾔普遍使⽤以后,促成了团队合作设计的热潮,⽽在此时,没有⼀个好的设计模式,软件设计⼏乎成了不可能完成的任务。
⼀般模式有4个基本要素:模式名称(pattern name)、问题(problem)、解决⽅案(solution)、效果(consequences)。
常见23种模式概述: 1)抽象⼯⼚模式(Abstract Factory):提供⼀个创建⼀系列相关或相互依赖对象的接⼝,⽽⽆需指定它们具体的类。
2)适配器模式(Adapter):将⼀个类的接⼝转换成客户希望的另外⼀个接⼝。
适配器模式使得原本由于接⼝不兼容⽽不能⼀起⼯作的类可以⼀起⼯作。
3)桥梁模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独⽴地变化。
4)建造模式(Builder):将⼀个复杂对象的构建与它的表⽰分离,使同样的构建过程可以创建不同的表⽰。
5)责任链模式(Chain of Responsibility):为解除请求的发送者和接收者之间耦合,⽽使多个对象都有机会处理这个请求。
将这些对象连成⼀条链,并沿着这条链传递该请求,直到有⼀个对象处理它。
6)命令模式(Command):将⼀个请求封装为⼀个对象,从⽽可⽤不同的请求对客户进⾏参数化;对请求排队或记录请求⽇志,以及⽀持可取消的操作。
7)合成模式(Composite):将对象组合成树形结构以表⽰“部分-整体”的层次结构。
它使得客户对单个对象和复合对象的使⽤具有⼀致性。
8)装饰模式(Decorator):动态地给⼀个对象添加⼀些额外的职责。
就扩展功能⽽⾔,它能⽣成⼦类的⽅式更为灵活。
9)门⾯模式(Facade):为⼦系统中的⼀组接⼝提供⼀个⼀致的界⾯,门⾯模式定义了⼀个⾼层接⼝,这个接⼝使得这⼀⼦系统更加容易使⽤。
10)⼯⼚⽅法(Factory Method):定义⼀个⽤于创建对象的接⼝,让⼦类决定将哪⼀个类实例化。
23种经典设计模式UML类图汇总2009年06月08日星期一上午 11:02创建型模式1、FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。
麦当劳和肯德基就是生产鸡翅的Factory工厂模式:客户类和工厂类分开。
消费者任何时候需要某种产品,只需向工厂请求即可。
消费者无须修改就可以接纳新产品。
缺点是当产品修改时,工厂类也要做相应的修改。
如:如何创建及如何向客户端提供。
2、BUILDER—MM最爱听的就是“我爱你”这句话了,见到不同地方的MM,要能够用她们的方言跟她说这句话哦,我有一个多种语言翻译机,上面每种语言都有一个按键,见到MM我只要按对应的键,它就能够用相应的语言说出“我爱你”这句话了,国外的MM也可以轻松搞掂,这就是我的“我爱你”builder。
(这一定比美军在伊拉克用的翻译机好卖)建造模式:将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。
建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。
建造模式可以强制实行一种分步骤进行的建造过程。
3、FACTORY METHOD—请MM去麦当劳吃汉堡,不同的MM有不同的口味,要每个都记住是一件烦人的事情,我一般采用Factory Method模式,带着MM到服务员那儿,说“要一个汉堡”,具体要什么样的汉堡呢,让MM直接跟服务员说就行了。
工厂方法模式:核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
4、PROTOTYPE—跟MM用QQ聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,需要时只要copy出来放到QQ里面就行了,这就是我的情话prototype了。
23种设计模式总结设计模式是一种解决反复出现的设计问题的方案,它们被广泛应用于软件设计和架构中。
在这里,我们列举了23种常用的设计模式,分别属于创建型、结构型和行为型模式。
一、创建型模式1. 工厂方法模式(Factory Method Pattern)定义一个创建对象的接口,但让子类决定实例化哪个类。
工厂方法模式是让类来进行对象的创建,而不是由你的代码直接new 出来。
2. 抽象工厂模式(Abstract Factory Pattern)提供一个接口,用于创建一系列相关或相互依赖的对象。
3. 单例模式(Singleton Pattern)确保一个类只有一个实例,并提供一个全局访问点。
4. 建造者模式(Builder Pattern)将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
5. 原型模式(Prototype Pattern)用原型实例指定创建对象的种类,并通过拷贝这些原型创建新的对象。
二、结构型模式6. 适配器模式(Adapter Pattern)将一个类的接口转换成客户希望的另外一个接口。
适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作。
7. 桥接模式(Bridge Pattern)将抽象部分与它的实现部分分离,使它们都可以独立地变化。
8. 组合模式(Composite Pattern)将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
9. 装饰器模式(Decorator Pattern)动态地给一个对象添加一些额外的职责,就增加功能来说,装饰器比生成子类更为灵活。
10. 外观模式(Facade Pattern)为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,使得这一子系统更加容易使用。
11. 享元模式(Flyweight Pattern)运用共享技术有效地支持大量细粒度的对象。
23种设计模式详解设计模式是在软件开发中常用的一种解决特定问题的通用解决方案。
下面是23种常见的设计模式及其详解:单例模式(Singleton Pattern):确保一个类只有一个实例,并提供全局访问点。
工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪个类。
抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
建造者模式(Builder Pattern):将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
原型模式(Prototype Pattern):用原型实例指定创建对象的种类,并通过复制这些原型来创建新的对象。
适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另一个接口。
适配器模式可以让原本由于接口不兼容而不能一起工作的类能够一起工作。
桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们都可以独立地变化。
装饰者模式(Decorator Pattern):动态地给一个对象添加一些额外的职责。
就扩展功能而言,装饰者模式比生成子类更为灵活。
组合模式(Composite Pattern):将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
外观模式(Facade Pattern):为子系统中的一组接口提供一个一致的界面,定义一个高层接口,使得这一子系统更加容易使用。
享元模式(Flyweight Pattern):运用共享技术有效地支持大量细粒度的对象。
代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。
责任链模式(Chain of Responsibility Pattern):为解除请求的发送者和接收者之间耦合,使多个对象都有机会处理这个请求。
23种设计模式UML 类图及对应示例代码1.DoFactory.GangOfFour.Abstract.StructuralAbstract Factory:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
工厂模式:客户类和工厂类分开。
消费者任何时候需要某种产品,只需向工厂请求即可。
消费者无须修改就可以接纳新产品。
缺点是当产品修改时,工厂类也要做相应的修改。
如:如何创建及如何向客户端提供。
using System;namespace DoFactory.GangOfFour.Abstract.Structural{///<summary>/// MainApp startup class for Structural/// Abstract Factory Design Pattern.///</summary>class MainApp{///<summary>/// Entry point into console application.///</summary>public static void Main(){// Abstract factory #1AbstractFactory factory1 = new ConcreteFactory1(); Client client1 = new Client(factory1);client1.Run();// Abstract factory #2AbstractFactory factory2 = new ConcreteFactory2(); Client client2 = new Client(factory2);client2.Run();// Wait for user inputConsole.Read();}}// "AbstractFactory"abstract class AbstractFactory{public abstract AbstractProductA CreateProductA();public abstract AbstractProductB CreateProductB();}// "ConcreteFactory1"class ConcreteFactory1 : AbstractFactory{public override AbstractProductA CreateProductA(){return new ProductA1();}public override AbstractProductB CreateProductB(){return new ProductB1();}}// "ConcreteFactory2"class ConcreteFactory2 : AbstractFactory{public override AbstractProductA CreateProductA() {return new ProductA2();}public override AbstractProductB CreateProductB() {return new ProductB2();}}// "AbstractProductA"abstract class AbstractProductA{}// "AbstractProductB"abstract class AbstractProductB{public abstract void Interact(AbstractProductA a); }// "ProductA1"class ProductA1 : AbstractProductA{}// "ProductB1"class ProductB1 : AbstractProductB{public override void Interact(AbstractProductA a) {Console.WriteLine(this.GetType().Name +" interacts with " + a.GetType().Name);}}// "ProductA2"class ProductA2 : AbstractProductA{}// "ProductB2"class ProductB2 : AbstractProductB{public override void Interact(AbstractProductA a){Console.WriteLine(this.GetType().Name +" interacts with " + a.GetType().Name);}}// "Client" - the interaction environment of the products class Client{private AbstractProductA AbstractProductA;private AbstractProductB AbstractProductB;// Constructorpublic Client(AbstractFactory factory){AbstractProductB = factory.CreateProductB();AbstractProductA = factory.CreateProductA();}public void Run(){AbstractProductB.Interact(AbstractProductA);}}}2.DoFactory.GangOfFour.Adapter.StructuralAdapter:将一个类的接口转换成客户希望的另一个接口,使得原来由于接口不兼容而不能一起工作的那些类可以一起工作。
23种设计模式详解设计模式是软件工程中的一种经验总结或优秀实践的规范化形式,它提供了在特定情境中解决特定问题的解决方案。
设计模式可以帮助开发人员更好地应对复杂的软件设计和开发过程中遇到的挑战,并提供了一种通用且可重用的方法来解决这些问题。
下面将详细介绍23种常见的设计模式:1. 单例模式(Singleton Pattern)单例模式确保类只能有一个实例,并提供全局访问该实例的接口。
2. 简单工厂模式(Simple Factory Pattern)简单工厂模式通过一个工厂类来封装对象的创建过程,实现了对象的创建与使用的解耦。
3. 工厂方法模式(Factory Method Pattern)工厂方法模式定义了一个用于创建对象的接口,由子类决定实例化哪个类。
4. 抽象工厂模式(Abstract Factory Pattern)抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体实现类。
5. 建造者模式(Builder Pattern)建造者模式将一个复杂对象的构建过程与其表示相分离,使得同样的构建过程可以创建不同的表示。
6. 原型模式(Prototype Pattern)原型模式通过复制现有对象来创建新的对象,避免了通过类的构造函数创建新对象的过程。
7. 适配器模式(Adapter Pattern)适配器模式将一个类的接口转换成客户希望的另一个接口,使得原本由于接口不兼容而不能在一起工作的类可以一起工作。
8. 桥接模式(Bridge Pattern)桥接模式将抽象部分与它的实现部分分离,使得它们可以独立地变化。
9. 装饰者模式(Decorator Pattern)装饰者模式动态地给一个对象添加一些额外的职责,而不需要子类化扩展该对象。
组合模式将对象组合成树形结构,并使得用户对单个对象和组合对象的使用具有一致性。
11. 外观模式(Facade Pattern)外观模式提供一个统一的接口,用于访问子系统中的一群接口。
二十三种设计模式类图0 引言谈到设计模式,绝对应该一起来说说重构。
重构给我们带来了什么?除了作为对遗留代码的改进的方法,另一大意义在于,可以让我们在写程序的时候可以不需事先考虑太多的代码组织问题,当然这其中也包括了应用模式的问题。
尽管大多数开发者都已经养成了写代码前先从设计开始的习惯,但是,这种程度的设计,涉及到到大局、到总体架构、到主要的模块划分我觉得就够了。
换句话说,这时就能写代码了。
这就得益于重构的思想了。
如果没有重构的思想,有希望获得非常高质量的代码,我们就不得不在开始写代码前考虑更多其实并非非常稳定的代码组织及设计模式的应用问题,那开发效率当然就大打折扣了。
在重构和设计模式的合理应用之下,我们可以相对较早的开始写代码,并在功能尽早实现的同时,不断地通过重构和模式来改善我们的代码质量。
所以,下面的章节中,在谈模式的同时,我也会谈谈关于常用的这些模式的重构成本的理解。
重构成本越高意味着,在遇到类似的问题情形的时候,我们更应该提前考虑应用对应的设计模式,而重构成本比较低则说明,类似的情形下,完全可以先怎么方便,怎么快怎么写,哪怕代码不是很优雅也没关系,回头再重构也很容易。
1 创建型1.1FactoryMethod思想:Factory Method的主要思想是使一个类的实例化延迟到其子类。
场景:典型的应用场景如:在某个系统开发的较早阶段,有某些类的实例化过程,实例化方式可能还不是很确定,或者实际实例化的对象(可能是需要对象的某个子类中的一个)不确定,或者比较容易变化。
此时,如果直接将实例化过程写在某个函数中,那么一般就是if-else或select-case代码。
如果,候选项的数目较少、类型基本确定,那么这样的if-else 还是可以接受的,一旦情形变得复杂、不确定性增加,更甚至包含这个构造过程的函数所在的类包含几个甚至更多类似的函数时,这样的if-else代码就会变得比较不那么容易维护了。
此时,应用本模式,可以将这种复杂情形隔离开,即将这类不确定的对象的实例化过程延迟到子类。
实现:该模式的典型实现方法就是将调用类定义为一个虚类,在调用类定义一个专门用于构造不确定的对象实例的虚函数,再将实际的对象实例化代码留到调用类的子类来实现。
如果,被构造的对象比较复杂的话,同时可以将这个对象定义为可以继承、甚至虚类,再在不同的调用类的子类中按需返回被构造类的子类。
重构成本:低。
该模式的重构成本实际上还与调用类自己的实例化方式相关。
如果调用类是通过Factory方式(此处“Factory方式”泛指对象的实例化通过Factory Method或Abstract Factory这样的相对独立出来的方式构造)构造的,那么,重构成本相对就会更低。
否则,重构时可能除了增加调用类的子类,还要将所有实例化调用类的地方,修改为以新增的子类代替。
可能这样的子类还不止一个,那就可以考虑迭代应用模式来改善调用类的实例化代码。
1.2AbstractFactory思想:不直接通过对象的具体实现类,而是通过使用专门的类来负责一组相关联的对象的创建。
场景:最典型的应用场景是:您只想暴露对象的接口而不想暴露具体的实现类,但是又想提供实例化对象的接口给用户;或者,您希望所有的对象能够集中在一个或一组类(通常称作工厂类)来创建,从而可以更方便的对对象的实例化过程进行动态配置(此时只需要修改工厂类的代码或配置)。
实现:该模式的实现是比较清晰简单的,如上图,就是定义创建和返回各种类对象实例的工厂类。
在最复杂而灵活的情形,无论工厂类本身还是被创建的对象类都可能需要有一个继承体系。
简单情形其实可以只是一个工厂类和需要被创建的对象类。
不一定非要像上图中结构那么完备(累赘)。
重构成本:中。
如果一开始所有的对象都是直接创建,例如通过new实例化的,而之后想重构为Abstract Factory模式,那么,很自然的我们需要替换所有直接的new实例化代码为对工厂类对象创建方法的调用。
考虑到像Resharper这样的重构工具的支持,找出对某个方法或构造函数的调用位置这样的操作相对还是比较容易,重构成本也不是非常高。
同时,重构成本还和被创建对象的构造函数的重载数量相关。
您需要根据实际情况考虑,是否工厂类要映射被创建对象的所有重载版本的构造函数。
1.3Builder思想:将一个类的创建过程和他的主体部分分离。
场景:该模式的典型的应用场景是:一个类的创建过程可能比较复杂,或者创建过程中的某些阶段可能会容易变化;或者多个类的创建过程比较类似,但是主体不同。
实现:在以上提到的两种场景中,我们就可以取出一个类的创建过程的代码,定义一个专门的Builder类,而在原来创建类对象实例的地方,将这个Builder类的实例作为参数传入。
还有第二个重点,就是Builder类可以将将整个创建过程分为几个阶段,每个阶段不必在类中直接实现,而可以通过继承体系在子类中实现,或者通过子类的方法过载来修改创建过程中的某个阶段,但是重用其他的阶段。
可以发现,该模式将一个对象的复杂创建过程重用到非常高的层次。
这正是它的意义所在。
重构成本:低。
该模式的重构成本我觉得是非常低的,因为一般来讲,创建过程的代码本来也就应该在原来的类的构造函数中,把它Extract出来就好了。
如果发现多个类的创建过程有比较多的代码重复或类似,那么就可以重用这些提取出来的Builder类或者Builder类中的某些阶段。
1.4Prototype思想:克隆一个已有的类的实例(大家相比都用过甚至写过类的Clone实现,应该很容易理解了)。
场景:应用Clone的场景应该说非常多,理想情况下我当然希望任何类都能Clone,需要的时候就能Clone一份一模一样的出来。
实现:这里将的实现主要之实现的表现形式,而不是如何用具体的语言来实现。
因此,只要为需要Clone能力的类定义一个Clone方法就行。
当然,一般,主流的程序语言框架都已经定义了通用的Clone接口(当然也可以自己定义),继承并实现该接口和方法就好。
重构成本:极低。
不多解释了吧。
1.5 Singleton思想:保证一个类只有一个唯一的实例。
场景:生活中有些对象就是只要一个就好了,我们的代码中为什么要每次都为这样的对象生成一个实例呢?实现:最简单的实现方式就是使用一个static型的类实例,每次对该对象的创建请求都返回这个static的唯一实例就行。
重构成本:极低。
2 结构型2.1Adapter思想:将一个类的接口转换成另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
场景:该模式的应用场景太多了,很多需要的功能模块的接口和我们需要的不完全一致或者有多余或不足,但是需要和我们的系统协同工作,通过Adapter把它包装一下就能让使它接口兼容了。
实现:定义一个Adapter类,包含需要包装的类,实现需要的其它接口,调用被包装的类的方法来实现需要的接口。
重构成本:低。
2.2Bridge思想:将一个类的抽象定义和具体实现解耦。
场景:该模式的典型应用场景是:一个类的抽象定义已经确定,但是,其实现代码甚至原理可能会不同。
比如:我们最熟悉的图形界面中的window的实现,无论在什么操作系统,什么平台的机器上,一个window应具有的抽象定义基本上是一致的,但是,其实现代码肯定会因为平台不同,机器的代码指令不同而不同。
此时,如果希望您写的window类能跨平台,应用Bridge模式就是一个好主意。
实现:该模式的实现方法很简单,就是除了定义类的抽象定义之外,将一个类的所有实现代码独立出一个实现类。
这样一来,无论是抽象定义还是实现类都能分别修改和重用,但只要两部分的交互接口不变,还是可以方便的互相组装。
当然,实际上也没有必要隔离出“所有实现代码”,只需要隔离需要的部分就行了。
因此,也可以说,从代码结构来看,Builder 模式是一种变种的Bridge模式的。
也经常有人将Bridge模式和接口相比较,如果隔离出所有的实现,那么的确接口的方式也能做到抽象定义和实现分离,但是,Bridge有其优势如下:一、究竟隔离多少代码到Bridge类中可以灵活确定,二、减少了总的类的数目,三、允许被隔离出来的Bridge类被其它的类直接共享使用。
重构成本:中。
将所有的(或很大部分)实现代码分离开来总还是一件不大,但是,也不小的事。
所以标个“中”在这里。
:)2.3Composite思想:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
场景:该模式的应用场景极其类似,比如像图形系统,如电路设计、UML建模系统,或者像web的显示元素等,都是那种需要整体和部分具有使用接口上的一定的一致性的需求的结构,实际上,我觉得这样的系统如果不使用Composite模式将会是惨不忍睹的。
实现:该模式的实现主要就是要表示整体或部分的所有类都继承自同一的基类或接口,从而拥有使用接口上一定的一致性。
重构成本:高。
2.4Decorator思想:为一个对象已有的子类添加一些额外的职责。
场景:该模式的使用场景,主要是有的时候我们不愿意定义逻辑上新的子类,因为没有新的逻辑含义上的子类概念,而只是想为一个已存在的子类附加一些职责。
实现:该模式的实现主要就是定义一个物理上的新的子类,但是,它只是包含要附加职责的类,传递外部对相同接口的调用,在这个传递调用的通道上附加额外的功能。
突然想到,Decorator模式是不是一定程度上也能代替DynamicProxy模式,从而成为一种AOP实现的方案呢?重构成本:低。
定义一个Decorator和一个已有类的逻辑上的子类,物理表现形式上都是一个子类,重构也确实不是难事。
2.5 Facade思想:为子系统中的一组接口提供一个一致的界面,这个接口使得这一子系统更加容易使用。
场景:当你要为一个复杂子系统提供一个简单接口时。
子系统往往因为不断演化而变得越来越复杂。
大多数模式使用时都会产生更多更小的类。
这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。
Facade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过Facade层。
客户程序与抽象类的实现部分之间存在着很大的依赖性。
引入Facade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
当你需要构建一个层次结构的子系统时,使用Facade模式定义子系统中每层的入口点。
如果子系统之间是相互依赖的,你可以让它们仅通过Facade进行通讯,从而简化了它们之间的依赖关系。
(这里直接引用了《设计模式迷你手册》,因为觉得它确实已经说得很明了了,下面类似的情形我直接引用原文的就不再注明了,这里先说明一下,感谢《手册》作者的这些优秀总结。