设计模式(Design Pattern)
一套被反复使用的,多数人知晓的,经过分类遍目的、代码设计经验的总结,使用设计模式是为了可重复使用代码,让代码更容易被他人理解并且提高代码的可靠性(目的)。设计模式是一种对软件系统中不断重复出现的设计问题的解决方案进行文档化的技术,也是一种共享专家设计经验的技术。
一、设计模式的分类
1. 基础型模式 (Fundamental Pattern)
Delegation pattern
Interface pattern
Proxy pattern
2. 创建型模式 (Creational Pattern)
抽象工厂模式(Abstract Factory)
工厂方法模式(Factory Method)
单例模式(Singleton)
3. 结构型模式 (Structural Pattern)
适配器模式(Adapter)
桥接模式(Bridge)
装饰模式(Decorator)
4. 行为型模式 (Behavioral Pattern)
职责链模式(Chain of Responsibility)
迭代器模式(Iterator)
观察者模式(Observer)
状态模式(State)
策略模式(Strategy)
访问者模式(Visitor)
5. 并发型模式 (Concurrency Pattern)
Active object
Monitor object
Thread pool pattern
二、设计模式详解
1.工厂方法模式(Factory Method)
应用场景
客户只知道创建产品的工厂名,而不知道具体的产品名。如 TCL 电视工厂、海信电视工厂等。
创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。
缺点
类的个数容易过多,增加复杂度
增加了系统的抽象性和理解难度
2.策略模式(Strategy Pattern)
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,关系图如下:
应用场景
一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中。
一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入它们各自的策略类中以代替这些条件语句。
系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时。
多个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。
缺点
客户端必须理解所有策略算法的区别,以便适时选择恰当的算法类。
策略模式造成很多的策略类,增加维护难度。
3.访问者模式(Visitor Pattern)
策略模式定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响到使用算法的客户。需要设计一个接口,为一系列实现类提供统一的方法,多个实现类实现该接口,设计一个抽象类(可有可无,属于辅助类),提供辅助函数,关系图如下:
应用场景
对象结构相对稳定,但其操作算法经常变化的程序。
对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。
对象结构包含很多类型的对象,希望对这些对象实施一些依赖于其具体类型的操作。
缺点
增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”。
破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性。
访问者模式依赖了具体类,而没有依赖抽象类。
4.装饰模式(Decorator)
指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
应用场景
当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类
当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰器模式却很好实现。
当对象的功能要求可以动态地添加,也可以再动态地撤销时。
缺点
- 装饰器模式会增加许多子类,过度使用会增加程序的复杂性。
5.迭代器模式(Iterator)
提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。
应用场景
当访问一个聚合对象的内容而无须暴露它的内部表示时。
当需要为聚合对象提供多种遍历方式时。
当需要为遍历不同的聚合结构提供一个统一的接口时。
缺点
- 装饰器模式会增加许多子类,过度使用会增加程序的复杂性。
6. 单例模式(Singleton)
单例对象能保证在一个JVM中,该对象只有一个实例存在。例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。
应用场景
需要频繁创建的一些类,使用单例可以降低系统的内存压力,减少 GC。。
某类只要求生成一个对象的时候,如一个班中的班长、每个人的身份证号等。
某些类创建实例时占用资源较多,或实例化耗时较长,且经常使用。
某类需要频繁实例化,而创建的对象又频繁被销毁的时候,如多线程的线程池、网络连接池等。
对于一些控制硬件级别的操作,或者从系统上来讲应当是单一控制逻辑的操作,如果有多个实例,则系统会完全乱套。
缺点
- 单例模式一般没有接口,扩展困难。如果要扩展,则除了修改原来的代码,没有第二种途径,违背开闭原则。
- ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210227181313628.gif