1. 创建型模式概述

创建型模式关注点是怎样创建出对象

降低系统的耦合度

使用者无需关注对象的创建细节

模式分类

  • 工厂模式:对象的创建由相关的工厂来完成
  • 建造者模式:对象的创建由一个建造者来完成
  • 原型模式:对象的创建由原来对象克隆完成
  • 单例模式:对象始终在系统中只有一个实例

    2. 单例模式

    2.1 特点和应用场景

    模式特点

  • 某个类只能有一个实例;(构造器私有)

  • 它必须自行创建这个实例;(自己编写实例化逻辑)
  • 它必须自行向整个系统提供这个实例;(对外提供实例化方法)

应用场景

  • 多线程中的线程池
  • 数据库的连接池
  • 系统环境信息
  • 上下文(ServletContext)

    2.2 饿汉式

    ```java public class HungrySingleton {

    private static final HungrySingleton INSTANCE = new HungrySingleton();

    private HungrySingleton() {

    }

    public static HungrySingleton getInstance() {

    1. return INSTANCE;

    }

}

  1. <a name="E7qhY"></a>
  2. ## 2.3 懒汉式
  3. ```java
  4. public class LazySingleton {
  5. // 防止指令重排序
  6. private static volatile LazySingleton instance;
  7. private LazySingleton() {
  8. }
  9. public static LazySingleton getInstance() {
  10. // 这里需要 double-check-lock
  11. if (instance == null) {
  12. synchronized (LazySingleton.class) {
  13. if (instance == null) {
  14. instance = new LazySingleton();
  15. }
  16. }
  17. }
  18. return instance;
  19. }
  20. }

3. 原型模式

3.1 特点和应用场景

模式特点

  • 原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能
  • 本体给外部提供一个克隆体进行使用

应用场景

  • 资源优化
  • 性能和安全要求
  • 一个对象多个修改者的场景
  • 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时可以考虑使用原型模式拷贝多个对象供调用者使用

浅拷贝和深拷贝

  • 浅复制:只是拷贝了基本类型的数据,而引用类型数据复制后也是会发生引用,浅复制仅仅是指向被复制的内存地址,如果原地址中对象被改变了,那么浅复制出来的对象也会相应改变
  • 深复制:在计算机中开辟了一块新的内存地址用于存放复制的对象

    3.2 案例

    ```java @Data public class Book implements Cloneable {

    private String title; private Image image;

    @Override protected Book clone() throws CloneNotSupportedException {

    1. Book book = (Book) super.clone();
    2. // 深拷贝
    3. book.setImage((Image) this.image.clone());
    4. return book;

    }

}

@Data @NoArgsConstructor @AllArgsConstructor public class Image implements Cloneable {

  1. public String name;
  2. @Override
  3. protected Object clone() throws CloneNotSupportedException {
  4. return super.clone();
  5. }

}

  1. ```java
  2. public class ProtoTypeTest {
  3. public static void main(String[] args) throws Exception{
  4. Book book1 = new Book();
  5. book1.setTitle("《三体》");
  6. book1.setImage(new Image("图片1"));
  7. // 以原型方式拷貝一份
  8. Book book2 = book1.clone();
  9. book2.getImage().setName("图片2");
  10. System.out.println(book1);
  11. System.out.println(book2);
  12. }
  13. }

4. 工厂模式

4.1 特点和应用场景

模式特点
工厂模式(Factory Pattern)提供了一种创建对象的最佳方式。我们不必关心对象的创建细节,只需要根据不同情况获取不同产品即可

应用场景

  • NumberFormat、SimpleDateFormatLoggerFactory
  • SqlSessionFactory(MyBatis)
  • BeanFactory(Spring)

工厂模式的退化

  • 当抽象工厂模式中每一个具体工厂类只创建一个产品对象,也就是只存在一个产品等级结构时,抽象工厂模式退化成工厂方法模式
  • 当工厂方法模式中抽象工厂与具体工厂合并,提供一个统一的工厂来创建产品对象,并将创建对象的工厂方法设计为静态方法时,工厂方法模式退化成简单工厂模式

4.2 简单工厂模式

简单工厂模式相当于是一个工厂中有各种产品,创建在一个类中,客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可
但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护

包含角色

  • Factory:工厂角色
  • 抽象产品角色
  • CarConcreteProduct:具体产品角色 ```java public interface Car {

    void run();

    class AoDi implements Car {

    1. @Override
    2. public void run() {
    3. System.out.println("奥迪跑起来");
    4. }

    }

    class JiLi implements Car {

    1. @Override
    2. public void run() {
    3. System.out.println("吉利跑起来");
    4. }

    }

}

  1. ```java
  2. public class CarFactory {
  3. /**
  4. * 简单工厂三个角色
  5. * Factory: 工厂角色
  6. * Product: 抽象产品
  7. * ConcreteProduct: 具体产品角色
  8. * <p>
  9. * 缺点: 违背开闭,扩展不易
  10. */
  11. public static Car createCar(String name) {
  12. if (name.equals("奥迪")) {
  13. return new Car.AoDi();
  14. }
  15. if (name.equals("吉利")) {
  16. return new Car.JiLi();
  17. }
  18. return null;
  19. }
  20. }

4.3 工厂方法模式

工厂方法模式又称多态性工厂模式。在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做
该核心类成为一个抽象工厂角色,仅负责给出具体工厂子类必须实现的接口,而不接触哪一个产品类应当被实例化这种细节

包含角色

  • Product:抽象产品
  • ConcreteProduct:具体产品
  • Factory:抽象工厂
  • ConcreteFactory:具体工厂 ```java public interface Car {

    void run();

    class AoDi implements Car {

    1. @Override
    2. public void run() {
    3. System.out.println("奥迪跑起来");
    4. }

    }

    class JiLi implements Car {

    1. @Override
    2. public void run() {
    3. System.out.println("吉利跑起来");
    4. }

    }

}

  1. ```java
  2. public interface CarFactory {
  3. /**
  4. * 工厂方法四个角色
  5. * Product: 抽象产品
  6. * ConcreteProduct: 具体产品角色
  7. * Factory: 抽象工厂
  8. * ConcreteFactory:具体工厂
  9. * <p>
  10. * 缺点: 系统复杂度增加,产品单一
  11. */
  12. Car createCar();
  13. class AoDiFactory implements CarFactory {
  14. @Override
  15. public Car createCar() {
  16. return new Car.AoDi();
  17. }
  18. }
  19. class JiLiFactory implements CarFactory {
  20. @Override
  21. public Car createCar() {
  22. return new Car.JiLi();
  23. }
  24. }
  25. }

4.4 抽象工厂模式

抽象工厂简单地说是工厂的工厂,抽象工厂可以创建具体工厂,由具体工厂来产生具体产品

  1. public interface Car {
  2. void run();
  3. class AoDi implements Car {
  4. @Override
  5. public void run() {
  6. System.out.println("奥迪跑起来");
  7. }
  8. }
  9. class JiLi implements Car {
  10. @Override
  11. public void run() {
  12. System.out.println("吉利跑起来");
  13. }
  14. }
  15. }
  1. public interface Pen {
  2. void write();
  3. class Pencil implements Pen {
  4. @Override
  5. public void write() {
  6. System.out.println("用铅笔写字");
  7. }
  8. }
  9. class BallPen implements Pen {
  10. @Override
  11. public void write() {
  12. System.out.println("用圆珠笔写字");
  13. }
  14. }
  15. }
  1. public interface IFactory {
  2. default Car createCar() {
  3. return null;
  4. }
  5. default Pen createPen() {
  6. return null;
  7. }
  8. /**
  9. * 抽象工厂创建的汽车抽象工厂
  10. */
  11. interface CarFactory extends IFactory {
  12. class AoDiFactory implements CarFactory {
  13. @Override
  14. public Car createCar() {
  15. return new Car.AoDi();
  16. }
  17. }
  18. class JiLiFactory implements CarFactory {
  19. @Override
  20. public Car createCar() {
  21. return new Car.JiLi();
  22. }
  23. }
  24. }
  25. /**
  26. * 抽象工厂创建的笔抽象工厂
  27. */
  28. interface PenFactory extends IFactory {
  29. class PencilFactory implements PenFactory {
  30. @Override
  31. public Pen createPen() {
  32. return new Pen.Pencil();
  33. }
  34. }
  35. class BallPenFactory implements PenFactory {
  36. @Override
  37. public Pen createPen() {
  38. return new Pen.BallPen();
  39. }
  40. }
  41. }
  42. }

5. 建造者模式

5.1 特点和应用场景

模式特点
与工厂模式的区别是:建造者模式更加关注细节,屏蔽过程而不屏蔽细节

包含角色

  • 产品角色(Product)
  • 抽象建造者(Builder)
  • 具体建造者(Concrete Builder)

应用场景

  • StringBuilder append()
  • Swagger ApiBuilder
  • Lombok @Builder 注解

    5.2 案例

    ```java @Data public class Phone {

    private String cpu;

    private String mem;

    private String disk;

}

  1. ```java
  2. public interface PhoneBuilder {
  3. PhoneBuilder cpu(String cpu);
  4. PhoneBuilder mem(String mem);
  5. PhoneBuilder disk(String disk);
  6. Phone build();
  7. /**
  8. * 产品角色(Product):Phone
  9. * 抽象建造者(Builder):PhoneBuilder
  10. * 具体建造者(Concrete Builder):XiaomiPhoneBuilder
  11. */
  12. class XiaomiPhoneBuilder implements PhoneBuilder {
  13. private Phone phone;
  14. public XiaomiPhoneBuilder() {
  15. this.phone = new Phone();
  16. }
  17. @Override
  18. public PhoneBuilder cpu(String cpu) {
  19. this.phone.setCpu(cpu);
  20. return this;
  21. }
  22. @Override
  23. public PhoneBuilder mem(String mem) {
  24. this.phone.setMem(mem);
  25. return this;
  26. }
  27. @Override
  28. public PhoneBuilder disk(String disk) {
  29. this.phone.setDisk(disk);
  30. return this;
  31. }
  32. @Override
  33. public Phone build() {
  34. return this.phone;
  35. }
  36. }
  37. }