关于27种常见设计模式的总结

目录

六大原则

  1. 开闭原则(Open Close Principle)

开闭原则的意思是:对扩展开放,对修改关闭。在程序须要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,咱们须要使用接口和抽象类,后面的具体设计中咱们会提到这点。java

  1. 里氏代换原则(Liskov Substitution Principle)

里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类能够出现的地方,子类必定能够出现。LSP 是继承复用的基石,只有当派生类能够替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也可以在基类的基础上增长新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,因此里氏代换原则是对实现抽象化的具体步骤的规范。算法

  1. 依赖倒转原则(Dependence Inversion Principle)

这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。数据库

  1. 接口隔离原则(Interface Segregation Principle)

这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另一个意思是:下降类之间的耦合度。因而可知,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调下降依赖,下降耦合。编程

  1. 迪米特法则,又称最少知道原则(Demeter Principle)

最少知道原则是指:一个实体应当尽可能少地与其余实体之间发生相互做用,使得系统功能模块相对独立。设计模式

  1. 合成复用原则(Composite Reuse Principle)

合成复用原则是指:尽可能使用合成/聚合的方式,而不是使用继承。缓存

建立型模式

这些设计模式提供了一种在建立对象的同时隐藏建立逻辑的方式,而不是使用 new 运算符直接实例化对象。这使得程序在判断针对某个给定实例须要建立哪些对象时更加灵活。多线程

工厂模式

工厂模式(Factory Pattern)是 Java 中最经常使用的设计模式之一。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。架构

在工厂模式中,咱们在建立对象时不会对客户端暴露建立逻辑,而且是经过使用一个共同的接口来指向新建立的对象。并发

适用场景

  1. 不少地方都须要建立某种对象时。
  2. 建立对象操做比较复杂,同时接口又须要统一时,同时又想要对外屏蔽时。
  3. 想要可以方便地扩展类型实现时。

模式缺点

  1. 工厂对于具体实现类型会产生依赖。
  2. 类型很是多时工厂类会变得很是复杂。

样例

public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public class ShapeFactory {
    public Shape getShape1() { return new Circle(); }
    public Shape getShape2() { return new Square(); }
    public Shape getShape(String shape) {
        switch (shape) {
            case "circle": return new Circle();
            case "square": return new Square();
        }
        return null;
    }
}

工厂方法模式

工厂方法(Factory Method)模式的意义是定义一个建立产品对象的工厂接口,将实际建立工做推迟到子类当中。核心工厂类再也不负责产品的建立,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可使系统在不修改具体工厂角色的状况下引进新的产品。高并发

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先彻底实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,能够应用于产品结果复杂的场合。

适用场景

  1. 同“工厂方法模式”
  2. 不但愿每次增长一个类型时都须要修改工厂基类时。

模式缺点

  1. 代码结构变得更复杂了。
  2. 工厂也变得更多了。

样例

public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public interface ShapeAbstractFactory {
    Shape getShape();
}
public class CircleFactory implements ShapeAbstractFactory {
    public Shape getShape() { return new Circle(); }
}
public class SquareFactory implements ShapeAbstractFactory {
    public Shape getShape() { return new Square(); }
}

抽象工厂方法模式

抽象工厂模式(Abstract Factory Pattern)隶属于设计模式中的建立型模式,用于产品族的构建。抽象工厂是全部形态的工厂模式中最为抽象和最具通常性的一种形态。抽象工厂是指当有多个抽象角色时使用的一种工厂模式。抽象工厂模式能够向客户端提供一个接口,使客户端在没必要指定产品的具体状况下,建立多个产品族中的产品对象。

工厂模式中的每个形态都是针对必定问题的解决方案,工厂方法针对的是一类产品;而抽象工厂模式针对的是多类产品,一类产品内又有多种实现类型的状况。

适用场景

  1. 一般状况下产品须要成套使用。
  2. 每套解决方案内部又存在多种组合解决方案。

模式缺点

  1. 代码结构变得更复杂了。

样例

public interface Shape {}
public class Circle implements Shape {}
public class Square implements Shape {}
public interface color {}
public class Red implements Color {}
public class Blue implements Color {}
public interface AbstractFactory {
    Shape getShape();
    Red getColor();
}
public class Factory1 implements AbstractFactory { ... }
public class Factory2 implements AbstractFactory { ... }

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。

这种模式涉及到一个单一的类,该类负责建立本身的对象,同时确保只有单个对象被建立。这个类提供了一种访问其惟一的对象的方式,能够直接访问,不须要实例化该类的对象。

注意:单例类只能有一个实例。

适用场景

  1. 逻辑相对简单的状况。
  2. 想要避免实例过多占用系统资源的状况。

模式缺点

  1. 修改单例对象的属性时,须要考虑多线程和高并发场景。

样例

public class Singleton {
    private volatile static Singleton singleton;
    private Singleton (){}  // 不容许经过new来实例化对象
    public static Singleton getSingleton() {
        if (singleton == null) {
            synchronized (Singleton.class) {
                if (singleton == null) {
                    singleton = new Singleton();
                }
            }
        }
        return singleton;
    }
}

建造者模式

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。

一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其余对象的。

适用场景

  1. 对象内部较为复杂,同时须要分离对象的建立与构建行为时。
  2. 一些内部基本部件相对稳定不变,而只是其组合常常变化的时候。
  3. 初始化一个对象时,参数过多,或者不少参数具备默认值时。

模式缺点

  1. 不适合建立差别性很大的产品类。
  2. 如内部变化复杂,会有不少的建造类。

样例

public interface Porudct { }
public interface Builder {
    Product buildPart(Product p);
}
public interface Director {
    Product getProduct();
}

原型模式

原型模式(Prototype Pattern)是用于建立重复的对象,同时又能保证性能。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。

这种模式是实现了一个原型接口,该接口用于建立当前对象的克隆。当直接建立对象的代价比较大时,则采用这种模式。例如,一个对象须要在一个高代价的数据库操做以后被建立。咱们能够缓存该对象,在下一个请求时返回它的克隆,在须要的时候更新数据库,以此来减小数据库调用。

适用场景

  1. 当一个系统应该独立于它的产品建立,构成和表示时。
  2. 当要实例化的类是在运行时指定时,例如,经过动态装载。
  3. 为了不一个与产品类层次平行的工厂类层次时。
  4. 当一个类的实例只能有几个不一样状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用什么时候的状态手工实例化该类更方便一些。

模式缺点

  1. 配备克隆方法须要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不必定容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。
  2. 必须实现Cloneable接口。

样例

public interface Cloneable {
    Object clone();
}

结构型模式

适配器模式

适配器模式(Adapter Pattern)是做为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式,它结合了两个独立接口的功能。这种模式涉及到一个单一的类,该类负责加入独立的或不兼容的接口功能。

适用场景

  1. 可让任何两个没有关联的类一块儿运行。
  2. 提升了类的复用。
  3. 增长了类的透明度。
  4. 灵活性好。

模式缺点

  1. 过多地使用适配器,会让系统很是零乱,不易总体进行把握。
  2. 因为 JAVA 至多继承一个类,因此至多只能适配一个适配者类,并且目标类必须是抽象类。

样例

略,简单来讲就是随意调用,相似于行为型地中介者模式。

桥接模式(称为嫁接更直观)

桥接(Bridge)是用于把抽象化与实现化解耦,使得两者能够独立变化。这种类型的设计模式属于结构型模式,它经过提供抽象化和实现化之间的桥接结构,来实现两者的解耦。

这种模式涉及到一个做为桥接的接口,使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。

咱们经过下面的实例来演示桥接模式(Bridge Pattern)的用法。其中,可使用相同的抽象类方法可是不一样的桥接实现类,来画出不一样颜色的圆。

适用场景

  1. 想要避免在抽象与实现之间存在永久绑定。
  2. 若是一个系统须要在构件的抽象化角色和具体化角色之间增长更多的灵活性,避免在两个层次之间创建静态的继承联系,经过桥接模式可使它们在抽象层创建一个关联关系。
  3. 对于那些不但愿使用继承或由于多层次继承致使系统类的个数急剧增长的系统,桥接模式尤其适用。
  4. 一个类存在两个独立变化的维度,且这两个维度都须要进行扩展。

模式缺点

  1. 桥接模式的引入会增长系统的理解与设计难度,因为聚合关联关系创建在抽象层,要求开发者针对抽象进行设计与编程。

样例

略,简单来讲就是将多种维度的属性从继承关系转化为组合关系。

过滤器模式

过滤器模式(Filter Pattern)或标准模式(Criteria Pattern)是一种设计模式,这种模式容许开发人员使用不一样的标准来过滤一组对象,经过逻辑运算以解耦的方式把它们链接起来。这种类型的设计模式属于结构型模式,它结合多个标准来得到单一标准。

适用场景

  1. 设计人员将整个系统的输入输出行为理解为单个过滤器行为的叠加与组合。这样能够将问题分解,化繁为简。
  2. 任何两个过滤器,只要它们之间传送的数据遵照共同的规约就能够相链接。每一个过滤器都有本身独立的输入输出接口,若是过滤器间传输的数据遵照其规约,只要用管道将它们链接就能够正常工做。
  3. 整个系统易于维护和升级:旧的过滤器能够被替代,新的过滤器能够添加到已有的系统上。软件的易于维护和升级是衡量软件系统质量的重要指标之一。在管道-过滤器模型中,只要遵照输入输出数据规约,任何一个过滤器均可以被另外一个新的过滤器代替,同时为加强程序功能,能够添加新的过滤器。这样,系统的可维护性和可升级性获得了保证。
  4. 支持并发执行,每一个过滤器做为一个单独的执行任务,能够与其它过滤器并发执行。过滤器的执行是独立的。不依赖于其它过滤器的。

模式缺点

  1. 效率较低。
  2. 过滤器若是组合状况复杂,那么会致使过滤器之间的结构变得复杂而且难以维护。

样例

public interface Filter {
    List<Object> filter(List<Object> list);
}

组合模式(树型模式更贴切)

组合模式(Composite Pattern),又叫部分总体模式,是用于把一组类似的对象看成一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及总体层次。这种类型的设计模式属于结构型模式,它建立了对象组的树形结构。

这种模式建立了一个包含本身对象组的类。该类提供了修改相同对象组的方式。

适用场景

  1. 想表示对象的部分-总体层次结构(树形结构)。
  2. 但愿用户忽略组合对象与单个对象的不一样,用户将统一地使用组合结构中的全部对象。

模式缺点

  1. 暂无。

样例

public interface Node {
    List<Node> getSubNodeList();
}

装饰器模式

装饰器模式(Decorator Pattern)容许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是做为现有的类的一个包装。

这种模式建立了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

适用场景

  1. 动态地给一个对象添加一些额外的职责,但又不想增长不少子类的状况。
  2. 装饰类和被装饰类能够独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式能够动态扩展一个实现类的功能。

模式缺点

  1. 多层装饰比较复杂。

样例

public interface Shape { }
public interface ShapeDecorator {
    void setShape(Shape shape);
    void doSomething();
}

外观模式

外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端能够访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。

这种模式涉及到一个单一的类,该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。

适用场景

  1. 为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

模式缺点

  1. 不符合开闭原则,若是要改东西很麻烦,继承重写都不合适。

样例

public interface Shape { }
public interface ShapeMaker {
    void doSomethingComplex();
}

享元模式

享元模式(Flyweight Pattern)主要用于减小建立对象的数量,以减小内存占用和提升性能。这种类型的设计模式属于结构型模式,它提供了减小对象数量从而改善应用所需的对象结构的方式。

享元模式尝试重用现有的同类对象,若是未找到匹配的对象,则建立新对象。

适用场景

  1. 系统中有大量对象。
  2. 这些对象消耗大量内存。
  3. 这些对象的状态大部分能够外部化。
  4. 这些对象能够按照内蕴状态分为不少组,当把外蕴对象从对象中剔除出来时,每一组对象均可以用一个对象来代替。
  5. 系统不依赖于这些对象身份,这些对象是不可分辨的。

模式缺点

  1. 提升了系统的复杂度,须要分离出外部状态和内部状态,并且外部状态具备固有化的性质,不该该随着内部状态的变化而变化,不然会形成系统的混乱。

样例

略,简而言之就是单例的复杂状况。

代理模式

在代理模式(Proxy Pattern)中,一个类表明另外一个类的功能。这种类型的设计模式属于结构型模式。

适用场景

  1. 想在访问一个类时作一些控制。

模式缺点

  1. 因为在客户端和真实主题之间增长了代理对象,所以有些类型的代理模式可能会形成请求的处理速度变慢。
  2. 实现代理模式须要额外的工做,有些代理模式的实现很是复杂。

样例

略,简单来讲就是替换类型并作一些外在包装。

行为型模式

责任链模式

顾名思义,责任链模式(Chain of Responsibility Pattern)为请求建立了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。

在这种模式中,一般每一个接收者都包含对另外一个接收者的引用。若是一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

适用场景

  1. 下降耦合度。它将请求的发送者和接收者解耦。
  2. 简化了对象。使得对象不须要知道链的结构。
  3. 加强给对象指派职责的灵活性。经过改变链内的成员或者调动它们的次序,容许动态地新增或者删除责任。
  4. 增长新的请求处理类很方便。

模式缺点

  1. 不能保证请求必定被接收。
  2. 系统性能将受到必定影响,并且在进行代码调试时不太方便,可能会形成循环调用。
  3. 可能不容易观察运行时的特征,有碍于除错。

样例

public interface Chain {
    Chain nextChain();
    void doSomething();
}

命令模式

命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找能够处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。

适用场景

  1. 行为请求者与行为实现者须要相互分离。
  2. 须要容易地添加新命令。
  3. 系统须要支持命令的撤销(Undo)操做和恢复(Redo)操做时,也能够考虑使用命令模式。

模式缺点

  1. 使用命令模式可能会致使某些系统有过多的具体命令类。

样例

public interface Receiver { void doAction(); }
public interface Command { void execute(); }
public interface Invoker { void execute(); }

解释器模式

解释器模式(Interpreter Pattern)提供了评估语言的语法或表达式的方式,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。

适用场景

  1. 能够将一个须要解释执行的语言中的句子表示为一个抽象语法树。
  2. 一些重复出现的问题能够用一种简单的语言来进行表达。
  3. 一个简单语法须要解释的场景。

模式缺点

  1. 可利用场景比较少。
  2. 对于复杂的文法比较难维护。
  3. 解释器模式会引发类膨胀。
  4. 解释器模式采用递归调用方法。

样例

public interface Expression { boolean interpret(String context); }
public class TerminalExpression implements Expression { …… }
public class AndExpression implements Expression { …… }

迭代器模式

迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中很是经常使用的设计模式。这种模式用于顺序访问集合对象的元素,不须要知道集合对象的底层表示。

适用场景

  1. 访问一个聚合对象的内容而无须暴露它的内部表示。
  2. 须要为聚合对象提供多种遍历方式。
  3. 为遍历不一样的聚合结构提供一个统一的接口。

模式缺点

  1. 因为迭代器模式将存储数据和遍历数据的职责分离,增长新的聚合类须要对应增长新的迭代器类,类的个数成对增长,这在必定程度上增长了系统的复杂性。

样例

public interface Iterator {
    Obejct first();
    boolean hasNext();
    Object next();
}
public interface Aggregate { Iterator createIterator(); }

中介者模式

中介者模式(Mediator Pattern)是用来下降多个对象和类之间的通讯复杂性。这种模式提供了一个中介类,该类一般处理不一样类之间的通讯,并支持松耦合,使代码易于维护。中介者模式属于行为型模式。

适用场景

  1. 下降了类的复杂度,将一对多转化成了一对一。
  2. 各个类之间的解耦。
  3. 符合迪米特原则。

模式缺点

  1. 中介者会庞大,变得复杂难以维护。

样例

public interface Mediator { void doAllThings(); }

备忘录模式

备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。

适用场景

  1. 给用户提供了一种能够恢复状态的机制,可使用户可以比较方便地回到某个历史的状态。
  2. 实现了信息的封装,使得用户不须要关心状态的保存细节。

模式缺点

  1. 消耗资源。若是类的成员变量过多,势必会占用比较大的资源,并且每一次保存都会消耗必定的内存。

样例

public interface Memento {
    void setState(int state);
    int getState();
}
public interface Originator {
    void restore(Memento memento);
    Memento createMemento();
}
public interface Caretaker {
    Memento getMemento(int i);
    void addMemento(Memento memento);
}

观察者模式(或者叫发布-订阅模式)

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。好比,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。

适用场景

  1. 当一个抽象模型有两个方面,其中一个方面依赖于另外一方面。将这两者封装在独立的对象中以使它们能够各自独立地改变和复用。
  2. 当对一个对象的改变须要同时(通知)改变其余对象,而不知道具体有多少对象须要被改变。
  3. 当一个对象必须通知其余对象,而它又不能假定其余对象是谁。换言之,不但愿这些对象是紧密耦合的。

模式缺点

  1. 若是一个被观察者对象有不少的直接和间接的观察者的话,将全部的观察者都通知到会花费不少时间。
  2. 若是在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能致使系统崩溃。
  3. 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

样例

public interface Observer {
    void update();
}
public interface Subject {
    void attach(Observer o)
    void detach(Observer o);
    void notify();
}

状态模式(或者叫发布-订阅模式)

在状态模式(State Pattern)中,类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。在状态模式中,咱们建立表示各类状态的对象和一个行为随着状态对象改变而改变的 context 对象。

适用场景

  1. 行为随状态改变而改变的场景。
  2. 条件、分支语句的代替者。

模式缺点

  1. 状态模式的使用必然会增长系统类和对象的个数。
  2. 状态模式的结构与实现都较为复杂,若是使用不当将致使程序结构和代码的混乱。
  3. 状态模式对"开闭原则"的支持并不太好,对于能够切换状态的状态模式,增长新的状态类须要修改那些负责状态转换的源代码,不然没法切换到新增状态,并且修改某个状态类的行为也需修改对应类的源代码。

样例

public interface State {
   void handle();
}
public interface Context {
    void setState(State s);
    State getState();
}

空对象模式

有两种含义:

  1. 在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查。
  2. Null 对象不是检查空值,而是反应一个不作任何动做的关系,这样的 Null 对象也能够在数据不可用的时候提供默认的行为。

在空对象模式中,咱们建立一个指定各类要执行的操做的抽象类和扩展该类的实体类,还建立一个未对该类作任何实现的空对象类,该空对象类将无缝地使用在须要检查空值的地方。

适用场景

  1. 想要避免使用空指针(或null对象)的状况。
  2. 想要默认状况下具备“不作任何操做”的行为的状况。

模式缺点

  1. 必须手动实现isNil方法(或isNull方法)。

样例

// 含义1:取代null的检查
public interface Nullable {
   boolean isNull();
}

// 含义2:不作任何动做的关系
public interface Command {
    void handle();
}
public class NullCommand implements Command {
    public void handle() {
        return;
    }
}

策略模式

在策略模式(Strategy Pattern)中,一个类的行为或其算法能够在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,咱们建立表示各类策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

适用场景

  1. 若是在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式能够动态地让一个对象在许多行为中选择一种行为。
  2. 一个系统须要动态地在几种算法中选择一种。
  3. 若是一个对象有不少的行为,若是不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

模式缺点

  1. 策略类会增多。
  2. 全部策略类都须要对外暴露。

样例

public interface Strategy {
   void strategy();
}

模板模式

在模板模式(Template Pattern)中,一个抽象类公开定义了执行它的方法的方式/模板。它的子类能够按须要重写方法实现,但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。

适用场景

  1. 有多个子类共有的方法,且逻辑相同。
  2. 重要的、复杂的方法,能够考虑做为模板方法。

模式缺点

  1. 每个不一样的实现都须要一个子类来实现,致使类的个数增长,使得系统更加庞大。

样例

略,其实继承状况下,就是对某些方法提供默认实现,对某些方法容许重写覆盖。

访问者模式

在访问者模式(Visitor Pattern)中,咱们使用了一个访问者类,它改变了元素类的执行算法。经过这种方式,元素的执行算法能够随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式,元素对象已接受访问者对象,这样访问者对象就能够处理元素对象上的操做。

适用场景

  1. 对象结构中对象对应的类不多改变,但常常须要在此对象结构上定义新的操做。
  2. 须要对一个对象结构中的对象进行不少不一样的而且不相关的操做,而须要避免让这些操做"污染"这些对象的类,也不但愿在增长新操做时修改这些类。

模式缺点

  1. 具体元素对访问者公布细节,违反了迪米特原则。
  2. 具体元素变动比较困难。
  3. 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

样例

public interface Visitor {
   void visit(Element e);
}
public interface Element {
   void accept(Visitor v);
}
// 一般在accept中,调用v.visit(this)来进行访问操做。
相关文章
相关标签/搜索