参考网址:Java Design Patterns
设计模式在软件开发者中非常流行。一个设计模式是对常用软件问题的一种清晰描述的解决方案。
使用设计模式的一些好处:
- 设计模式已经被定义,并提供了解决重复问题的行业标准方法;因此,如果我们明智地使用设计模式,可以节省时间。我们可以在基于Java的项目中,使用许多Java设计模式。
- 使用设计模式促进了可重用性,从而产生了更健壮和易于维护的代码。 它有助于降低软件产品的总拥有成本(TCO).
- 由于设计模式已经被定义,它使我们的代码易于理解和调试。这促进了更快的开发速度,并且新团队成员能够轻松理解。
Java设计模式分为三类:创建型、结构型和行为型设计模式。
这篇文章作为所有Java设计模式文章的索引。
创建型设计模式
创建型设计模式为特定情况下以最佳方式实例化对象提供解决方案。
1. 单例模式(Singleton Pattern)
单例模式限制了类的实例化,并确保在Java虚拟机中只存在一个类的实例。单例模式的实现一直是开发者之间具有争议性的话题。
注意:了解更多关于单例设计模式的信息。
2. 工厂模式(Factory Pattern)
工厂设计模式用于当我们有一个超类具有多个子类,并且根据输入,我们需要返回其中一个子类时。该模式将类的实例化责任从客户程序移至工厂类。我们可以在工厂类上应用单例模式,或将工厂方法设为静态。
3. 抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式类似于工厂模式,是工厂的工厂。如果你熟悉Java中的工厂设计模式,你会注意到我们有一个单一的工厂类,根据提供的输入返回不同的子类,并且工厂类使用if-else或switch语句来实现这一点。在抽象工厂模式中,我们摆脱了if-else块,为每个子类拥有一个工厂类,然后有一个抽象工厂类,根据输入工厂类返回相应的子类。
4. 建造者模式(Builder Pattern)
建造者模式是为了解决工厂和抽象工厂设计模式在对象包含大量属性时出现的一些问题而引入的。该模式通过提供一种逐步构建对象并提供一个实际返回最终对象的方法,解决了大量可选参数和不一致状态的问题。
5. 原型模式(Prototype Pattern)
原型模式用于当对象创建成本高昂、需要大量时间和资源,并且已经存在一个类似的对象时。因此,该模式提供了一种机制,将原始对象复制到一个新对象,然后根据我们的需要进行修改。该模式使用Java的克隆功能来复制对象。原型设计模式要求被复制的对象应该提供复制功能,而不是由任何其他类完成。然而,是否使用对象属性的浅复制或深复制取决于需求,并且是一个设计决策。
结构型设计模式
结构型设计模式提供了创建类结构的不同方法(例如,使用继承和组合从小对象创建大对象)。
1. 适配器模式(Adapter Pattern)
适配器设计模式是结构型设计模式之一,用于使两个不相关的接口能够一起工作。将这些不相关接口连接起来的对象称为适配器。
2. 组合模式(Composite Pattern)
组合模式在我们需要表示部分-整体层次结构时使用。当我们需要以一种方式创建结构,使得结构中的对象必须以相同的方式对待时,我们可以应用组合设计模式。
3. 代理模式(Proxy Pattern)
代理模式提供了另一个对象的占位符来控制对它的访问。当我们想要提供对功能进行受控访问时,就会使用这种模式。
4. 享元模式(Flyweight Pattern)
享元设计模式用于需要创建大量对象的情况。由于每个对象都消耗内存空间,这对于内存较低的设备(如移动设备或嵌入式系统)可能是至关重要的,因此可以应用享元设计模式来减少内存负载,通过共享对象。
Java中的字符串池实现是享元模式实现的最佳示例之一。
5. 外观模式(Facade Pattern)
外观模式用于帮助客户端应用程序轻松地与系统交互。
6. 桥接模式(Bridge Pattern)
当接口和实现中都存在接口层次结构时,桥接设计模式用于将接口与实现解耦,并隐藏实现细节,不让客户程序直接依赖于实现。桥接设计模式的实现遵循了组合优于继承的理念。
7. 装饰器模式(Decorator Pattern)
装饰器设计模式用于在运行时修改对象的功能。同时,同一类的其他实例不会受到影响,因此个别对象获得了修改后的行为。装饰器设计模式是结构型设计模式之一(如适配器模式、桥接模式或组合模式),并使用抽象类或接口与组合实现。我们使用继承或组合来扩展对象的行为,但这是在编译时完成的,并且适用于该类的所有实例。我们不能在运行时添加任何新功能或删除任何现有行为 - 这就是装饰器模式的用处所在。
行为型设计模式
行为型模式提供了更好地对象间交互的解决方案,以及如何提供松耦合和灵活性以便轻松扩展。
1. 模板方法模式(Template Method Pattern)
模板方法模式是一种行为设计模式,用于创建方法存根,并将一些实现步骤延迟到子类中。模板方法定义了执行算法的步骤,并且可以提供一个默认实现,这对于所有或某些子类可能是共同的。
2. 中介者模式(Mediator Pattern)
中介者设计模式用于在系统中为不同对象提供集中的通信介质。如果对象直接相互交互,系统组件之间将紧密耦合,这会使可维护性成本更高,且不易于轻松扩展。中介者模式专注于为对象之间的通信提供中介,并实现对象之间的松耦合。中介者作为对象之间的路由器工作,它可以有自己的逻辑来提供通信方式。
3. 责任链模式(Chain of Responsibility Pattern)
责任链模式用于在软件设计中实现松耦合,其中来自客户端的请求被传递给一系列对象来处理。然后链中的对象将决定谁来处理请求,以及是否需要将请求发送到链中的下一个对象。
我们知道在try-catch块代码中可以有多个catch块。这里每个catch块都是处理特定异常的处理器。因此,当try块中发生异常时,它会被发送到第一个catch块进行处理。如果catch块无法处理它,它将请求转发到链中的下一个对象(即下一个catch块)。如果即使最后一个catch块也无法处理它,异常将被抛出到调用程序之外的链。
4. 观察者模式(Observer Pattern)
观察者设计模式在你关心对象状态并希望在任何变化时得到通知时非常有用。在观察者模式中,观察另一个对象状态的对象称为观察者,而被观察的对象称为主题。
Java通过java.util.Observable
类和java.util.Observer
接口提供了一个内置平台来实现观察者模式。然而,它并不广泛使用,因为实现有限,大多数时候我们不希望仅仅为了实现观察者模式而继承一个类,因为Java在类中不提供多重继承。Java消息服务(JMS)使用观察者模式和中介者模式来允许应用程序订阅和发布数据给其他应用程序。
5. 策略模式(Strategy Pattern)
策略模式用于当我们针对特定任务有多个算法时,客户端决定在运行时使用的实际实现。策略模式也被称为策略模式。我们定义多个算法,并让客户端应用将要使用的算法作为参数传递。
这种模式的一个最好的例子是Collections.sort()
方法,它接受Comparator
参数。根据比较器接口的不同实现,对象以不同的方式进行排序。
6. 命令模式(Command Pattern)
命令模式用于在请求-响应模型中实现松耦合。在这种模式中,请求被发送给调用者,调用者将其传递给封装的命令对象。命令对象将请求传递给接收者的适当方法,以执行特定的操作。
7. 状态模式(State Pattern)
状态设计模式用于当一个对象根据其内部状态改变其行为时。如果我们必须根据对象的状态改变其行为,我们可以在对象中拥有一个状态变量,并使用if-else条件块根据状态执行不同的操作。状态模式用于通过上下文和状态实现提供一种系统化和松耦合的方式来实现这一点。
8. 访问者模式(Visitor Pattern)
访问者模式用于当我们需要在一组类似类型的对象上执行操作时。借助访问者模式,我们可以将操作逻辑从对象中移到另一个类中。
9. 解释器模式(Interpreter Pattern)
解释器模式用于定义语言的语法表示,并提供一个解释器来处理这个语法。
10. 迭代器模式(Iterator Pattern)
迭代器模式是行为模式之一,用于提供一种标准的方式来遍历一组对象。迭代器模式在Java集合框架中被广泛使用,其中迭代器接口提供了遍历集合的方法。该模式还用于根据我们的需求提供不同类型的迭代器。迭代器模式隐藏了对集合进行遍历的实际实现,客户程序使用迭代器方法。
11. 备忘录模式(Memento Pattern)
备忘录设计模式用于当我们想要保存对象的状态以便稍后恢复时。该模式用于以这样一种方式实现,即对象的保存状态数据在对象外部不可访问,这保护了保存状态数据的完整性。
备忘录模式由两个对象实现 - 发起者和看管者。发起者是需要保存和恢复状态的对象,它使用内部类来保存对象的状态。内部类称为“备忘录”,它是私有的,因此不能从其他对象访问。