设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理的运用设计模式可以完美的解决很多问题,每种模式在现在中都有相应的原理来与之对应,每一个模式描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是它能被广泛应用的原因。
设计模式分类:
创建型模式:对象实例化的模式,创建型模式用于解耦对象的实例化过程
常用的有:单例模式、工厂模式(工厂方法和抽象工厂)、建造者模式。
不常用的有:原型模式。
结构型模式:把类或对象结合在一起形成一个更大的结构
常用的有:代理模式、桥接模式、装饰者模式、适配器模式。
不常用的有:门面模式、组合模式、享元模式。
行为型模式:类和对象如何交互,及划分责任和算法。
常用的有:观察者模式、模板模式、策略模式、职责链模式、迭代器模式、状态模式。
不常用的有:访问者模式、备忘录模式、命令模式、解释器模式、中介模式。

文章目录

  • 创建型模式
    • 单例模式(Singleton Pattern)
    • 工厂模式(Factory Pattern)
    • 抽象工厂模式(Abstract Factory Pattern)
    • 原型模式(Prototype Pattern)
    • 建造者模式(Builder Pattern)
  • 结构型模式
    • 适配器模式(Adapter Pattern)
    • 桥梁/桥接模式(Bridge Pattern)
    • 组合模式(Composite Pattern)
    • 装饰者模式(Decorator Pattern)
    • 外观/门面模式(Facade Pattern)
    • 享元模式(Flyweight Pattern)
    • 代理模式(Proxy Pattern)
  • 行为型模式
    • 访问者模式(Visitor Pattern)
    • 模板方法模式(Template Method Pattern)
    • 策略模式(Strategy Pattern)
    • 状态模式(State Pattern)
    • 观察者模式(Observer Pattern)
    • 备忘录模式(Memento Pattern)
    • 中介者模式(Mediator Pattern)
    • 迭代器模式(Iterator Pattern)
    • 解释器模式(Interpreter Pattern)
    • 命令模式(Command Pattern)
    • 责任链模式(Chain of Responsibility Pattern)

创建型模式

单例模式(Singleton Pattern)

定义:Ensure a class has only one instance, and provide a global point of access to it.(确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。)
饿汉模式:(在单例类定义的时候(即在main函数之前)就进行实例化,是线程安全的)

/*** 单例模式(线程安全)* @author zjq*/
public class Singleton {private static final Singleton singleton = new Singleton();/**限制产生多个对象*/private Singleton(){}/*** 通过该方法获得实例对象* @return*/public static Singleton getSingleton(){return singleton;}/*** 类中其他方法,尽量是static*/public static void doSomething(){}
}

使用场景:

  • 要求生成唯一序列号的环境;
  • 在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;
  • 创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源;
  • 需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当然,也可以直接声明为static的方式)。

懒汉模式:(在第一次用到类实例的时候才会去实例化,线程不安全)

public class Singleton {private static Singleton singleton = null;//限制产生多个对象private Singleton(){}//通过该方法获得实例对象public static Singleton getSingleton(){if(singleton == null){singleton = new Singleton();}return singleton;}
}

解决办法:
在getSingleton方法前加synchronized关键字,也可以在getSingleton方法内增加synchronized来实现。最优的办法是如通用代码那样写。

工厂模式(Factory Pattern)

定义:Define an interface for creating an object,but let subclasses decide which class to instantiate.Factory Method lets a class defer instantiation to subclasses.(定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。)
工厂模式类图:

Product为抽象产品类负责定义产品的共性,实现对事物最抽象的定义;
AbstractFactory为抽象创建类,也就是抽象工厂,具体如何创建产品类是由具体的实现工厂ConcreteCreator完成的。
简单工厂模式:
一个模块仅需要一个工厂类,没有必要把它产生出来,使用静态的方法
多个工厂类:
每个人种(具体的产品类)都对应了一个创建者,每个创建者独立负责创建对应的产品对象,非常符合单一职责原则
代替单例模式:
单例模式的核心要求就是在内存中只有一个对象,通过工厂方法模式也可以只在内存中生产一个对象
延迟初始化:
ProductFactory负责产品类对象的创建工作,并且通过prMap变量产生一个缓存,对需要再次被重用的对象保留
使用场景:jdbc连接数据库,硬件访问,降低对象的产生和销毁

抽象工厂模式(Abstract Factory Pattern)

定义:Provide an interface for creating families of related or dependent objects without specifying their concrete classes.(为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。)
抽象工厂模式通用类图:

抽象工厂类代码:

public abstract class AbstractCreator {//创建A产品家族public abstract AbstractProductA createProductA();//创建B产品家族public abstract AbstractProductB createProductB();
}

使用场景:
一个对象族(或是一组没有任何关系的对象)都有相同的约束。
涉及不同操作系统的时候,都可以考虑使用抽象工厂模式。

原型模式(Prototype Pattern)

定义:Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype.(用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。)
原型模式类图:

原型模式通用代码:

public class PrototypeClass implements Cloneable{//覆写父类Object方法@Overridepublic PrototypeClass clone(){PrototypeClass prototypeClass = null;try {prototypeClass = (PrototypeClass)super.clone();} catch (CloneNotSupportedException e) {//异常处理}return prototypeClass;}
}

原型模式实际上就是实现Cloneable接口,重写clone()方法。
使用原型模式的优点:

  • 性能优良

原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。

  • 逃避构造函数的约束

这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的(参见13.4节)。
使用场景:

  • 资源优化场景

类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。

  • 性能和安全要求的场景

通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。

  • 一个对象多个修改者的场景

一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
浅拷贝和深拷贝: