[23种设计模式汇总]结构型模式_装饰模式
23种设计模式全解析

23种设计模式全解析分类: DesignPattern 2013-06-24 10:56 54864人阅读评论(29) 收藏举报目录(?)[+]一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。
用一个图片来整体描述一下:二、设计模式的六大原则总原则:开闭原则(Open Close Principle)开闭原则就是说对扩展开放,对修改关闭。
在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。
所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。
想要达到这样的效果,我们需要使用接口和抽象类等,后面的具体设计中我们会提到这点。
1、单一职责原则不要存在多于一个导致类变更的原因,也就是说每个类应该实现单一的职责,如若不然,就应该把类拆分。
2、里氏替换原则(Liskov Substitution Principle)里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。
里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。
LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
里氏代换原则是对“开-闭”原则的补充。
实现“开-闭”原则的关键步骤就是抽象化。
而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
—— From Baidu 百科里氏替换原则中,子类对父类的方法尽量不要重写和重载。
23种基本的设计模式

23种基本的设计模式设计模式指的是在软件设计过程中,面对特定问题时能够重复使用的解决方案。
设计模式可帮助开发人员更完整、更高效地解决问题,并提高代码的可读性和可维护性。
在软件开发中,有23种基本的设计模式。
1. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供全局访问点。
2. 工厂模式(Factory Pattern):通过工厂方法创建对象,而不是直接实例化。
3. 抽象工厂模式(Abstract Factory Pattern):提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。
4. 建造者模式(Builder Pattern):将一个复杂对象的构造与它的表示分离,使得同样的构造过程可以创建不同的表示。
5. 原型模式(Prototype Pattern):通过复制已有对象来创建新对象,而不是通过实例化。
6. 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的接口。
7. 桥接模式(Bridge Pattern):将抽象部分与它的实现部分分离,使它们可以独立变化。
9. 装饰器模式(Decorator Pattern):动态地给一个对象添加额外的职责。
10. 外观模式(Facade Pattern):为子系统中的一组接口提供统一的接口,以提供更高级别的接口。
11. 享元模式(Flyweight Pattern):通过共享已存在的对象来减少内存占用。
12. 代理模式(Proxy Pattern):为其他对象提供一个代理以控制对这个对象的访问。
13. 模板方法模式(Template Method Pattern):定义一个操作中的算法骨架,而将一些步骤延迟到子类中。
14. 策略模式(Strategy Pattern):定义一系列的算法,将其逐个封装起来,并使它们可以相互替换。
15. 观察者模式(Observer Pattern):定义了一种一对多的依赖关系,让多个观察者对象同时监听其中一个主题对象。
23种设计模式的详解

23种Java设计模式设计模式分两类:创建型模式、行为型模式。
一、创建型模式 :1、FACTORY—追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然口味有所不同,但不管你带MM去麦当劳或肯德基,只管向服务员说“来四个鸡翅”就行了。
麦当劳和肯德基就是生产鸡翅的Factory1、工厂模式:客户类和工厂类分开。
消费者任何时候需要某种产品,只需向工厂请求即可。
消费者无须修改就可以接纳新产品。
缺点是当产品修改时,工厂类也要做相应的修改。
如:如何创建及如何向客户端提供。
2、BUILDER—MM最爱听的就是“我爱你”这句话了,见到不同地方的MM,要能够用她们的方言跟她说这句话哦,我有一个多种语言翻译机,上面每种语言都有一个按键,见到MM我只要按对应的键,它就能够用相应的语言说出“我爱你”这句话了,国外的MM也可以轻松搞掂,这就是我的“我爱你” builder。
(这一定比美军在伊拉克用的翻译机好卖)2、建造模式:将产品的内部表象和产品的生成过程分割开来,从而使一个建造过程生成具有不同的内部表象的产品对象。
建造模式使得产品内部表象可以独立的变化,客户不必知道产品内部组成的细节。
建造模式可以强制实行一种分步骤进行的建造过程。
3、FACTORY METHOD—请MM去麦当劳吃汉堡,不同的MM有不同的口味,要每个都记住是一件烦人的事情,我一般采用Factory Method模式,带着MM到服务员那儿,说“要一个汉堡”,具体要什么样的汉堡呢,让MM直接跟服务员说就行了。
3、工厂方法模式:核心工厂类不再负责所有产品的创建,而是将具体创建的工作交给子类去做,成为一个抽象工厂角色,仅负责给出具体工厂类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节。
4、PROTOTYPE—跟MM用QQ聊天,一定要说些深情的话语了,我搜集了好多肉麻的情话,需要时只要copy出来放到QQ里面就行了,这就是我的情话prototype了。
23种设计模式

结构图
角色与理解
核心代码
享元模式(FlyweightPattern)(实现对象的复用)
定义
结构图
将系统中细粒度的相同的或者
相似的对象以共享的方式存放
在享元池中供客户端使用。
01
02
角色与理解
03
04
核心代码
代理模式(ProxyPattern)(控制对象的访问)
2014 2015 2016 2017
工厂模式 (Fa ctor yPa t t er n )
简单工厂模式 (SimpleFactor
yPattern)
工厂方法模式 (Factor yM eth
odPattern)
抽象工厂模式 (AbstractFact
or yPa tter n )
简单工厂模式(SimpleFactor yPattern)
04 核心代 码
建造者模式(BuilderPattern)(复杂对象的构建)
定义
结构图
将一个复杂对象的构建与它
的表示分离,使同样的构建 过程可以创建不同的表示
01
02
角色与理解
03
04
核心代码
结构型 (StructuralPatter ns)
适配器模式(AdapterPattern)(不兼容结构的协调)
定义
通过一个代理对象或者占位符来控制对原对象的访问。
结构图
角色与理解
核心代码
行为型 (BehavioralPatte rns)
责任链模式 (ChainOfResponsibilityPatter n)(请求的链式处理)
定义 将请求发送者和请求接受者解
耦,让请求的接受者形成链式操 作,所有人都能够接受接受到请 求,直到有人处理请求。
Java开发中的23种设计模式详解

Java开发中的23种设计模式详解一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。
用一个图片来整体描述一下:二、设计模式的六大原则1、开闭原则(Open Close Principle)开闭原则就是说对扩展开放,对修改关闭。
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。
想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。
里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。
LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
里氏代换原则是对“开-闭”原则的补充。
实现“开-闭”原则的关键步骤就是抽象化。
而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
—— From Baidu 百科3、依赖倒转原则(Dependence Inversion Principle)这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。
面向对象设计的23个设计模式详解

面向对象设计的23个设计模式详解面向对象设计是一种广泛应用于软件开发的思想,其核心在于将数据和操作封装在一起形成对象,并通过各种方式进行交互和组合,从而实现复杂的功能。
在这一过程中,设计模式起到了非常重要的作用,可以有效地提高代码的可读性、可维护性和可扩展性。
本文将对23种常见的设计模式进行详解。
一、创建型模式1.简单工厂模式简单工厂模式属于创建型模式,其目的是提供一个工厂类,使得创建对象的过程更加简单。
在这种模式中,使用者只需要提供所需对象的参数,而无需关心对象的具体实现细节。
简单工厂模式适合于对象创建过程较为简单的情况。
2.工厂方法模式工厂方法模式是简单工厂模式的进一步扩展,其核心在于将工厂类进行接口抽象化,使得不同的工厂类可以创建不同的对象实例。
工厂方法模式适合于对象创建过程较为复杂的情况。
它可以为工厂类添加新的产品类型,而不会影响原有的代码。
3.抽象工厂模式抽象工厂模式是工厂方法模式的进一步扩展,其目的是提供一个可以创建一系列相关或者独立的对象的接口。
在抽象工厂模式中,使用者只需要关心所需对象组合的类型,而无需关注对象的具体实现过程。
4.建造者模式建造者模式也是一种创建型模式,其目的在于将复杂对象分解为多个简单的部分,并将其组装起来形成复杂对象实例。
在建造者模式中,使用者只需要关注所需对象以及它们的组合方式,而无需关心对象的具体实现过程。
5.原型模式原型模式是一种基于克隆的创建型模式,其核心在于通过复制现有的对象实例来创建新的对象。
在原型模式中,对象实例的创建过程与对象所包含的状态密切相关。
原型模式适合于创建复杂对象实例,且这些对象实例之间是相对独立的情况。
二、结构型模式6.适配器模式适配器模式是一种结构型模式,其目的在于将一个类的接口转换为另一个类所能使用的接口。
在适配器模式中,使用者可以通过不同的适配器实现对象之间的互相调用。
7.桥接模式桥接模式是一种结构型模式,其目的在于将抽象部分与实现部分相互分离,从而使得两者可以独立变化。
23种设计模式资料

一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。
用一个图片来整体描述一下:二、设计模式的六大原则1、开闭原则(Open Close Principle)开闭原则就是说对扩展开放,对修改关闭。
在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。
所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。
想要达到这样的效果,我们需要使用接口和抽象类,后面的具体设计中我们会提到这点。
2、里氏代换原则(Liskov Substitution Principle)里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。
里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。
LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。
里氏代换原则是对“开-闭”原则的补充。
实现“开-闭”原则的关键步骤就是抽象化。
而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。
—— From Baidu 百科3、依赖倒转原则(Dependence Inversion Principle)这个是开闭原则的基础,具体内容:真对接口编程,依赖于抽象而不依赖于具体。
4、接口隔离原则(Interface Segregation Principle)这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。
23种设计模式整理

public interface Builder { void buildPartA(); void buildPartB(); void buildPartC(); Product getResult(); }
8.
}
9. }
10.
11. interface IFactory {
12. public IProduct createProduct();
13. }
14.
15. class Factory implements IFactory {
16. public IProduct createProduct() {
22. }
23. class Factory implements IFactory{
24. public IProduct1 createProduct1() {
25.
return new Product1();
26. }
27. public IProduct2 createProduct2() {
建造者模式的使用场景 1)相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。 2)多个部件或零件,都可以装配到一个对象中,但产生的运行结果又不相同时,可以使用该模式 3)产品类非常复杂,或产品类中的调用顺序不同产生了不同的效能,此使用建造者模式很合适 4)在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中
28.
return new Product2();
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
装饰模式概述在软件系统中,有时候我们会使用继承来扩展对象的功能,但是由于继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀。
如何使“对象功能的扩展”能够根据需要来动态地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响将为最低?这就是本文要讲的Decorator模式。
意图动态地给一个对象添加一些额外的职责。
就增加功能来说,Decorator模式相比生成子类更为灵活。
[GOF 《设计模式》]结构图图1 Decorator模式结构图生活中的例子装饰模式动态地给一个对象添加额外的职责。
不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。
在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。
图2 使用有画框的画作为例子的装饰模式对象图装饰模式解说在软件开发中,经常会遇到动态地为一个对象而不是整个类增加一些功能的问题,还是以我惯用的记录日志的例子来说明吧(也许在Decorator模式里面用这个例子不是特别合适)。
现在要求我们开发的记录日志的组件,除了要支持数据库记录DatabaseLog和文本文件记录TextFileLog 两种方式外,我们还需要在不同的应用环境中增加一些额外的功能,比如需要记录日志信息的错误严重级别,需要记录日志信息的优先级别,还有日志信息的扩展属性等功能。
在这里,如果我们不去考虑设计模式,解决问题的方法其实很简单,可以通过继承机制去实现,日志类结构图如下:图3实现代码如下:public abstract class Log{public abstract void Write(string log);}public class DatabaseLog : Log{public override void Write(string log){//......记录到数据库中}}public class TextFileLog : Log{public override void Write(string log){//......记录到文本文件中}}需要记录日志信息的错误严重级别功能和记录日志信息优先级别的功能,只要在原来子类DatabaseLog和TextFileLog的基础上再生成子类即可,同时需要引进两个新的接口IError和I Priority,类结构图如下:图4实现代码如下:public interface IError{void SetError();}public interface IPriority{void SetPriority();}public class DBErrorLog : DatabaseLog, IError {public override void Write(string log){base.Write(log);}public void SetError(){//......功能扩展,实现了记录错误严重级别}}public class DBPriorityLog : DatabaseLog, IPriority {public override void Write(string log){base.Write(log);}public void SetPriority(){//......功能扩展,实现了记录优先级别}}public class TFErrorLog : TextFileLog, IError{public override void Write(string log){base.Write(log);}public void SetError(){//......功能扩展,实现了记录错误严重级别}}public class TFPriorityLog : TextFileLog, IPriority{public override void Write(string log){base.Write(log);}public void SetPriority(){//......功能扩展,实现了记录优先级别}}此时可以看到,如果需要相应的功能,直接使用这些子类就可以了。
这里我们采用了类的继承方式来解决了对象功能的扩展问题,这种方式是可以达到我们预期的目的。
然而,它却带来了一系列的问题。
首先,前面的分析只是进行了一种功能的扩展,如果既需要记录错误严重级别,又需要记录优先级时,子类就需要进行接口的多重继承,这在某些情况下会违反类的单一职责原则,注意下图中的蓝色区域:图5实现代码:public class DBEPLog : DatabaseLog, IError, IPriority {public override void Write(string log){SetError();SetPriority();base.Write(log);}public void SetError(){//......功能扩展,实现了记录错误严重级别}public void SetPriority(){//......功能扩展,实现了记录优先级别}}public class TFEPLog : DatabaseLog, IError, IPriority{public override void Write(string log){SetError();SetPriority();base.Write(log);}public void SetError(){//......功能扩展,实现了记录错误严重级别}public void SetPriority(){//......功能扩展,实现了记录优先级别}}其次,随着以后扩展功能的增多,子类会迅速的膨胀,可以看到,子类的出现其实是DatabaseLog 和TextFileLog两个子类与新增加的接口的一种排列组合关系,所以类结构会变得很复杂而难以维护,正如象李建忠老师说的那样“子类复子类,子类何其多”;最后,这种方式的扩展是一种静态的扩展方式,并没有能够真正实现扩展功能的动态添加,客户程序不能选择添加扩展功能的方式和时机。
现在又该是Decorator模式出场的时候了,解决方案是把Log对象嵌入到另一个对象中,由这个对象来扩展功能。
首先我们要定义一个抽象的包装类LogWrapper,让它继承于Log类,结构图如下:图6实现代码如下:public abstract class LogWrapper : Log{private Log _log;public LogWrapper(Log log){_log = log;}public override void Write(string log){_log.Write(log);}}现在对于每个扩展的功能,都增加一个包装类的子类,让它们来实现具体的扩展功能,如下图中绿色的区域:图7实现代码如下:public class LogErrorWrapper : LogWrapper{public LogErrorWrapper(Log _log):base(_log){}public override void Write(string log){SetError(); //......功能扩展base.Write(log);}public void SetError(){//......实现了记录错误严重级别}}public class LogPriorityWrapper : LogWrapper{public LogPriorityWrapper(Log _log): base(_log){}public override void Write(string log){SetPriority(); //......功能扩展base.Write(log);}public void SetPriority(){//......实现了记录优先级别}}到这里,LogErrorWrapper类和LogPriorityWrapper类真正实现了对错误严重级别和优先级别的功能的扩展。
我们来看一下客户程序如何去调用它:public class Program{public static void Main(string[] args){Log log = new DatabaseLog();LogWrapper lew1 = new LogErrorWrapper(log);//扩展了记录错误严重级别lew1.Write("Log Message");LogPriorityWrapper lpw1 = new LogPriorityWrapper(log);//扩展了记录优先级别lpw1.Write("Log Message");LogWrapper lew2 = new LogErrorWrapper(log);LogPriorityWrapper lpw2 = new LogPriorityWrapper(lew2); //这里是lew2//同时扩展了错误严重级别和优先级别lpw2.Write("Log Message");}}注意在上面程序中的第三段装饰才真正体现出了Decorator模式的精妙所在,这里总共包装了两次:第一次对log对象进行错误严重级别的装饰,变成了lew2对象,第二次再对lew2对象进行装饰,于是变成了lpw2对象,此时的lpw2对象同时扩展了错误严重级别和优先级别的功能。
也就是说我们需要哪些功能,就可以这样继续包装下去。
到这里也许有人会说LogPriorityWrapper类的构造函数接收的是一个Log对象,为什么这里可以传入LogErrorWrapper对象呢?通过类结构图就能发现,LogErrorWrapper类其实也是Log类的一个子类。
我们分析一下这样会带来什么好处?首先对于扩展功能已经实现了真正的动态增加,只在需要某种功能的时候才进行包装;其次,如果再出现一种新的扩展功能,只需要增加一个对应的包装子类(注意:这一点任何时候都是避免不了的),而无需再进行很多子类的继承,不会出现子类的膨胀,同时Decorator模式也很好的符合了面向对象设计原则中的“优先使用对象组合而非继承”和“开放-封闭”原则。
.NET中的装饰模式1..NET中Decorator模式一个典型的运用就是关于Stream,它存在着如下的类结构:图8可以看到, BufferedStream和CryptoStream其实就是两个包装类,这里的Decorator模式省略了抽象装饰角色(Decorator),示例代码如下:class Program{public static void Main(string[] args){MemoryStream ms =new MemoryStream(new byte[] { 100,456,864,222,567});//扩展了缓冲的功能BufferedStream buff = new BufferedStream(ms);//扩展了缓冲,加密的功能CryptoStream crypto = new CryptoStream(buff);}}通过反编译,可以看到BufferedStream类的代码(只列出部分),它是继承于Stream类:public sealed class BufferedStream : Stream{// Methodsprivate BufferedStream();public BufferedStream(Stream stream);public BufferedStream(Stream stream, int bufferSize);// Fieldsprivate int _bufferSize;private Stream _s;}2.在Enterprise Library中的DAAB中有一个DbCommandWrapper的包装类,它实现了对IDbCommand类的包装并提供了参数处理的功能。