Common Design Patterns

Six principles of design patterns
    1. Single Responsibility: Do not have more than one reason for a class change, that is, a class is only responsible for one responsibility. (Synthetic multiplexing means more use of aggregation);
    2. Liskov substitution: all references to the base class must be able to transparently use the objects of its subclasses;
    3. Dependency inversion: high-level modules should not depend on low-level modules, both should depend on their abstractions; abstractions should not depend on details, and details should depend on abstractions;
    4. Interface isolation: programming for the interface, not for the implementation. The client should not depend on interfaces it does not need, and the dependencies of one class on another should be built on the smallest interface;
    5. Law of Demeter: An object should keep the least knowledge of other objects;
    6. The principle of separation of dynamic and static: find out the parts of the application that may need to be changed, separate them out, and do not mix them with code that does not need to be changed;

behavior pattern
    1. The mediator model
      Use a mediator object to encapsulate a series of object interactions. The mediator makes each object do not need to show the interaction, so that the coupling is loose and the interaction between them is changed independently.
        The structure of the mediator pattern
  • Abstract mediator: define the interface between the colleague object and the mediator object, which is used for communication between various colleague classes, generally including one or several abstract event methods, which are implemented by subclasses;
  • Mediator implementation class: Inherited from the abstract mediator, implements the event method defined in the abstract mediator, receives messages from a colleague class, and then affects other colleague classes through the message;
        Advantages and disadvantages of the mediator model
  • Reduce the coupling between colleague classes, convert the one-to-many relationship between objects into a one-to-one relationship, and make the relationship between objects easy to understand and maintain.
    2. Template method pattern
        Defines the framework of an algorithm in action, but defers steps to subclasses, allowing subclasses to redefine certain steps in the algorithm without changing the algorithm structure.
        Template method structure
  • The template method pattern consists of an abstract class and a (or a group of) implementation classes through an inheritance structure;
  • Abstract method: The parent class only declares but does not implement it, but defines the specification, and then implements it by its subclass;
  • Template method: It is declared by an abstract class and implements the main logic function. It is generally declared as a final type, indicating that the main logic function cannot be overridden in subclasses;
        Pros and cons of the template approach
  • Easy to expand, easy to maintain, more flexible, the behavior is controlled by the parent class, and the subclass is implemented; each different implementation requires a subclass to implement, resulting in an increase in the number of classes and a huge system.
    3. Strategy Mode
       Define algorithm families and encapsulate them separately so that they can be replaced with each other. This mode makes the changes of the algorithms independent of the customers who use the algorithms; the strategy mode is the encapsulation of algorithms, and a series of algorithms are encapsulated into corresponding classes respectively. And these classes implement the same interface and are interchangeable with each other. The difference between the strategy mode and the template method mode is that in the template method mode, the main body of the calling algorithm is in the abstract parent class, while in the strategy mode, the main body of the calling algorithm is encapsulated in the encapsulation class Contex, and the abstract strategy Strategy is generally Is an interface, the purpose is only to define the specification, which generally does not contain logic.
        Structure of the Strategy Pattern
  • Encapsulation class (Contex): The second encapsulation of the strategy is to avoid the direct invocation of the strategy by the high-level module;
  • Abstract strategy: usually an interface. If there is repeated logic code in each class, an abstract class is used to encapsulate this part of the code. At this time, the strategy pattern is more like the template method pattern;
  • Specific strategy: a set of classes that encapsulate algorithms, and these classes can be freely replaced according to requirements;
      eg: For the duck class interface Duck (Context), the duck classes ColorDuck of different colors implement the interface Duck, expand the duck behavior interface FlyBehavior and the duck sound interface QuackBehavior horizontally in the interface Duck, and add a reference to the behavior interface FlyBehavior in the Duck interface. And the reference of QuackBehavior of the call interface, and the implementation class (implementation algorithm) of the specific behavior interface FlyBehavior can freely implement the flying behavior as needed, and the implementation class (implementation algorithm) of the call interface QuackBehavior can freely implement the behavior of the call as needed.
        Advantages and disadvantages of the strategy pattern
  • It is easy to extend, and the strategy classes can be switched freely, avoiding the use of multiple conditional judgments; strategy maintenance brings additional overhead, and all strategies must be exposed to the client (caller), because the client decides which strategy to use.
    4. Observer Pattern
        Define a one-to-many dependency between objects, so that when each object changes state, all objects that depend on it will be notified and automatically updated;
        The structure of the observer pattern
  • Observed: The class contains a Vector container for storing the observer object, the container observer adds the method add(), the container observer deletes the method delete(), and the observer notifies the method notify();
  • 观察者:观察者一般是一个接口,只有一个update()方法,在被观察者状态发生变化时,这个方法被触发调用;
  • 具体被观察者:使用这个角色便于扩展,在此角色中定义具体的业务逻辑;
  • 具体观察者:观察者接口的具体实现,定义被观察者对象状态发生变化时所需要处理的逻辑;
         观察者模式的优缺点
  • 观察者和被观察者是抽象耦合,容易进行扩展,观察者模式是一种常用的触发机制,它形成了条触发链,依次对各个观察者的方法进行处理;当观察者较多时,性能较差,并且在链式结构中,比较容易出现循环引用的错误,造成系统崩溃;
  • Java语言中有一个接口Observer,以及他的实现类Observable,对观察者角色进行了实现。
    5.访问者模式
  • 封装某些作用于某种数据结构中各元素的操作,他可以在不改变数据结构的前提下定义作用于这些元素的新的操作。即通过在业务类中添加含中间类实例参数的方法,中间类中添加含有业务类实例参数的方法,通过调用中间类的方法调用业务类的方法逻辑,则中间类就是业务类的访问者。
        访问者模式结构
  • 抽象访问者:抽象类或者接口,声明访问者可以访问哪些元素;
  • 访问者:实现抽象访问者所声明的方法;
  • 抽象元素类:接口或者抽象类,声明接受哪一类访问者访问。一般包含两类方法,一种是本身业务逻辑方法,另一种是接受哪些访问者来访问。
  • 元素类:实现抽象元素所声明的accept方法;
  • 结构对象:一个元素容器,一般包含一个容纳多个不同类、不同接口的容器(List、Set、Map);
        访问者模式的优缺点
  • 符合单一职责原则,扩展性、灵活性良好;具体元素对访问者公布细节,违反了迪米特法则,增加新的元素比较困难。
    6.命令模式
  • 将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能,即把一系列的操作写到一个方法中,然后供客户端调用。
        命令模式结构
  • Command类:是一个抽象类声明需要执行的命令,且对外公布一个execute方法用来执行命令;
  • ConcreteCommand类:Command类的实现类,对抽象类中声明的方法进行实现;
  • Client类:最终的客户端调用类;
  • Invoker类:调用者负责调用命令;
  • Receiver:接收者,负责接受命令并且执行命令;
        命令模式的优缺点
  • 封装性、扩展性很好;如果命令很多的话会增加代码的复杂度;
    7.责任链 模式
  • 使多个对象都有机会处理请求,从而避免了请求的发送者和请求的接收者之间的耦合关系。将这些对象连成一条链,并且沿着这条链传递该请求,直到有对象处理它为止。
        责任链模式结构
  • 抽象处理类:包含一个指向下一个处理类的成员变量nextHandler和一个处理请求的方法handRequest,handRequest的主要思想是。如果满足处理条件,则由本处理类来进行处理,否则由nextHandler来处理;
  • 具体处理类:具体处理类主要是对具体的处理逻辑和适用条件进行具体的实现;
        责任链模式优缺点
  • 降低了耦合度,简化了对象,增强给对象指派职责的灵活性;不能保证请求一定会被接收,对系统的性能有一定的影响。
  • Java中的Filter类即是责任链模式的典型实现。
    8.迭代器模式
  • 提供一种方法访问一个容器对象中各个元素,而又不暴露该对象的内部细节,是目前使用最多的设计模式之一。
        迭代器模式结构
  • 抽象容器:一般是一个接口,提供一个iterator()方法,如Collection、List、Set;
  • 具体容器:抽象容器的具体实现类,如ArrayList、HashSet;
  • 抽象迭代器:定义遍历元素所需要的方法,取第一个元素first(),取下一个元素next(),判断遍历是否结束hasNext(),移除当前对象remove();
  • 迭代器实现:实现迭代器接口中定义的方法,完成集合的迭代;
        迭代器模式优缺点
  • 封装性良好,简化了集合对象的遍历方式;由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。
    9.备忘录 模式
  • 在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态;
         备忘录模式结构
  • 发起人:记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备忘录数据;
  • 备忘录:负责存储发起人对象的内部状态,在需要的时候提供给发起人需要的内部状态;
  • 管理角色:对备忘录进行管理,保存和提供备忘录;
        备忘录模式优缺点
  • 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态,实现了信息的封装,使得用户不需要关心状态的保存细节;消耗资源很大。
    10.状态 模式
  • 状态模式主要解决的是:控制一个对象内部的状态转换的条件表达式过于复杂时的情况,且客户端调用之前不需要了解具体状态。它把状态的判断逻辑转到表现不同状态的一系列类当中,可以把复杂的判断逻辑简化。维持开闭原则且方便维护,状态模式是让各个状态对象自己知道其下一个处理的对象是谁!即在状态子类编译时在代码上就设定好了!使用状态模式时,每个状态对应一个具体的状态类,使结构分散,类的数量变得很多!使得程序结构变得稍显复杂,阅读代码时相对之前比较困难。

创建型模式
  • 单例模式
      确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,节省内存空间,提高系统性能,全局访问。没有接口,不能继承,与单一职责原则冲突。
  • 工厂方法模式
        定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法是一个类的实例化延迟到子类。使代码结构清晰,有效的封装变化,对调   用者屏蔽具体的产品类,降低耦合度。每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
  • 抽象工厂模式
        为创建一组相关或者相互依赖的对象提供一个接口,而无需指定他们的具体类;抽象工厂是工厂方法的升级版本,它用来创建一组相关或者相互依赖的对象。可以在类的内部对产品族进行约束,产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
  • 建造者模式
        将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不通的表示,建造者模式与工厂模式相比较只是多了一个“导演类”的角色,所以建造者模式一般用来创建过程更为复杂的对象。
  • 原型模式
        通过拷贝原型实例来创建新的对像,简化了对象的创建过程。模式使用Object类的本地方法clone,它直接操作内存中的二进制流,故提高了创建对象的性能。
结构模式
  • 适配器模式
        建一个类的接口转化为客户希望的另一个接口;使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作提高了类的复用、增加了类的透明度、灵活性好;但过多地使用适配器,会让系统非常零乱,不易整体进行把握。
  • 桥接模式
        将抽象部分和它的实现部分分离,使得他们可以独立的变化;抽象和实现的分离、优秀的扩展能力、实现细节对客户透明;桥接模式的引入会增加系统的理解与设计难度。
  • 组合模式
        将对象组合成树形结构以表示“部分-整体”的层次结构;高层模块调用简单、节点自由增加在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。
  • 装饰模式
        动态的给一个对象添加一些额外的职责;代理模式主要是控制对某个特定对象访问,而装饰模式主要是为了给对象添加行为装饰类和被装饰类可以独立发展,易于扩展,降低了耦合。
  • 外观模式
        为子系统中的一组接口提供一个一致的界面;减少系统相互依赖、提高灵活性、提高了安全性;不符合开闭原则,如果要改东西很麻烦,继承重写都不合适。
  • 代理模式
        为其它对象提供一种代理以控制这个对象的访问;代理模式主要是控制对某个特定对象访问,而装饰模式主要是为了给对象添加行为职责清晰、高扩展性、智能化,但系统的系统性能下降、实现过程相对复杂。

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325754306&siteId=291194637