创建型模式:工厂方法模式、抽象工厂模式、建造者模式、原型模式

本文深入讲解了设计模式的三大类别:创建型模式、结构型模式和行为型模式,包括单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式等。详细解析了每种模式的实现方式、优缺点及适用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

几种设计模式

  1. 创建型模式(五种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式、。
  2. 结构型模式(七种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  3. 行为型模式(十一种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式

单例模式

看上篇文章

简单工厂模式

在这里插入图片描述

简单工厂模式

新增一个工厂类:在工厂类通过不同的类型创建不同的产品
优点在于:工厂类包含了必要的逻辑判断,根据客户端传入的条件动态实例化相关的功能类,对于客户端来说,通过工厂生产产品的方式,去除了与具体产品的依赖
缺点在于:当需要增加新得产品时,需要修改工厂类,违背了开放-封闭原则

工厂方法模式:

在这里插入图片描述
新增一个抽象工厂类,它定义了创建产品方法的标准。当需要新增产品时,只需要新增新产品的具体工厂类,而不需要修改工厂类。

优化工厂方法

通过反射机制和配置文件,实现不修改客户端代码的基础上,修改具体工厂类。

  1. 获取配置文件的类名
  2. 通过反射创建该对象
  3. 客户端调用上述方法

工厂方法的隐藏(客户端)

在抽象工厂中直接调用抽象产品的业务方法,客户端只需要创建工厂对象就可以调用产品对象的业务方法

工厂方法优缺点

优点:

  1. 客户端创建产品,只需知道产品对应的工厂,而无需关心具体的产品类以及创建细节
  2. 系统中加入新产品,无需修改现有代码,只需要添加一个具体工厂类和具体产品即可。完全符合开闭原则
    缺点:
  3. 系统添加新产品需要添加具体工厂类 和 具体产品类,增加系统复杂度
  4. 客户端使用抽象层调用方法,增加系统理解难度

工厂方法使用场景

  1. 客户端无需知道它所需要创建具体的类以及具体过程
  2. 想要使得系统更容易扩展

抽象工厂模式

抽象工厂:

工厂方法模式生产一类产品,而抽象工厂模式生产一个产品族多类产品。例如生产不同品牌的多类型产品
抽象工厂:声明了一组方法,每一个方法对应一类产品。
具体工厂:每个具体工厂生产一个品牌的产品,每个品牌生产多类产品。

抽象工厂实现

public interface abstractFactory{
    public AbstractProductA createProductA(); //创建类型一的商品
    public AbstractProductB createProductB(); //创建类型一的商品
}
//创建海尔品牌的多类产品
public class ConcreateFactoryHaior extends abstractFactory{
    public AbstractProductA createProductA(){}; //创建类型一的商品
    public AbstractProductB createProductB(){}; //创建类型一的商品
}
//创建美的品牌的多类产品
public class ConcreateFactoryMedia extends abstractFactory{
    public AbstractProductA createProductA(){}; //创建类型一的商品
    public AbstractProductB createProductB(){}; //创建类型一的商品
}

抽象工厂优缺点

优点:

  1. 增加产品族很方便,无需修改系统
  2. 客户端限制同一个产品族的对象一起使用
  3. 客户端创建产品时,只需知道产品对应的工厂,而无需关心具体的产品类以及创建细节
    缺点:
  4. 增加产品等级结构很麻烦,需要修改抽象类,违反开闭原则

抽象工厂适用环境

  1. 客户端无需知道具体的产品和创建过程就可创建对象
  2. 系统中存在多于一个的产品族
  3. 系统需要限制同一个产品族的产品在一起使用
  4. 系统产品等级结构稳定

建造者模式

建造者模式只关乎如何通过各个组件如何一步步的构建复杂对象,将客户端的使用与复杂对象的构建相分离,客户端无需知道复杂对象的装配方式,只需要知道建造者的类型即可。
例如汽车拥有多个组成部件:车轮,方向盘,发动机等,但大多数用户只会直接使用汽车。

建造者模式的数据结构

  1. 抽象构建者(Builder):
    a) 创建复杂对象各个部分的方法:buildPartA(),buildPartB()
    b) 返回复杂对象的接口getResult()
  2. 具体构建者(ConcreteBuilder):实现各个部件的具体构造方法,然后返回复杂对象
  3. 复杂产品(Product):包含多个组成部分
  4. 指挥者(Director):通过使用Builder的方法,安排复杂对象的构建次序。客户端使用构建者模式构建对象时,只需传入具体的构建者对象,与指挥者交互就可以。

构建者模式实现—电脑的组装

电脑销售相当于指挥者,客户只需要告诉销售电脑类型,电脑销售则调用电脑组装人员组装一台电脑

## 创建产品类
public class product(){
    private string parta;
    private string partb;
    private string partc;
}
## 定义抽象构建者
public abstract class Builder{
    protected Product product=new Product();

    public abstract void buildPartA();
    public abstract void buildPartB();
    public abstract void buildPartC();

    public Product getResult(){
         return product;
    }
}
##  定义具体构建者,不同的具体构建者,设置具体部件都不一样
public class ConcreteBuilder1 extend Builder{
    public abstract void buildPartA(){
         product.setPartA("A1");
    };
    public abstract void buildPartB(){
         product.setPartA("A1");
    };
    public abstract void buildPartC(){
         product.setPartA("A1");
    };
}
##  定义指挥者1. 隔离客户端与创建过程  2. 控制产品创建过程(builderBuildX是否被调用,多个builderBuildX的先后次序)
public class Director(){
    private Builder builder;
    public Director(Builder builder){
        this.builder=builder;
    }
    //产品构建与组装方法
    public Product construct(){
         builder.builderA();
         builder.builderB();
         builder.builderC();
         return builder.getResult();
    }
}

指挥者Director:指导具体构建者如何构建产品,它按一定次序调用Builder的buildPartX()方法,并向客户端返回一个完整对象。

指挥者优化

  1. 省略Director后,合并到Builder
  2. Builder类加返回boolean值的钩子函数,指挥者通过钩子函数决定是否调用Builder类的方法

建造者的优缺点

优点:

  1. 客户端无需知道产品细节,通过相同的构建过程构建不同的产品对象
  2. 客户端使用不同的具体构建者构建不同的产品对象
  3. 系统精细化控制产品的构建过程,使得构建过程更清晰
    缺点:
  4. 构建者创建的产品需要具有较多共同点
  5. 产品变化不能频繁

构建者模式适合的场景

  1. 构建的产品对象有复杂的内部结构
  2. 产品对象组成部分之间有相互依赖,需要指定生成顺序

原型模式(Prototype)

通过复制一个已有对象来获取更多相同或者类似的对象,从而提高相同类型对象的创建效率。
创建对象的工厂就是原型类自身,工厂方法由克隆方法来实现。

原型模式数据结构

  1. 抽象原型类Prototype:声明克隆方法的接口
  2. 具体原型类ConcretePrototype:实现克隆方法,返回一个自己克隆的对象

根据复制对象时是否包含对象中的引用类型成员变量,分为浅克隆,深克隆
浅克隆:
若原型对象是值对象,则复制一份给克隆对象
若原型对象是引用对象,则复制一份对象的引用
深克隆:
不管是值对象,还是引用对象,都会复制一份克隆对象

原型对象的实现-创建周报

public abstract class prototype{
    public abstract Prototype clone();
}

public class ConcretePrototype extends Prorotype{
      private String attr; //成员变量
     
      public Prototype clone(){
           Prototype prototype=new ConcretePrototype();
           prototype.setAttr(this.attr);
           return prototype;
      }
}

java语言中的clone方法和Cloneable接口
在java中实现Cloneable接口重写clone方法实现对象的浅克隆

  1. 实现浅克隆
public abstract class prototype{
    public abstract Prototype clone();
}

public class ConcretePrototype extends Prorotype implement Cloneable{
      private Attachment attachment;
      private String name;
      private String date;
      private Sting content;
     
      public Prototype clone(){
           Object obj=null;
           try{
               object=super.clone();
           }catch(ClassNotSupportException e){
               syso("not support");
           }
           return (Prototype)obj;
      }
}
  1. 实现深克隆
public class ConcretePrototype extends Prorotype implement Serializable{
      private Attachment attachment;
      private String name;
      private String date;
      private Sting content;
     
      public Prototype deepClone(){
              // 将对象写入流中
              ByteArrayOutputStream bao=new ByteArrayOutputStream();
              ObjectOutputSream oos=new ObjectOutputSream (bao):
              oos.writeObject(this);
              // 将对象从流中读出
              ByteArrayInputStream bis=new ByteArrayInputStream(bao.toByteArray());
              ObjectInputStream ois=new ObjectInputStream(bis);
              return (ConcretePrototype )ois.readObject();
      }
}

原型管理器

多个原型对象存储在一个集合中,相当于一个克隆对象的工厂

通过原型管理器对原型对象进行管理,方便对原型对象进行编程。

public class PrototypeManager{
     private Map map=new HashMap();
     public PrototypeManager{
         map.put("a",new ConcretePrototypeA());
         map.put("b",new ConcretePrototypeB());
     }
     public void add(String key,Prototype prototype){
         map.put(key,prototype);
     }
     public Prototype get(Stirng key){
         return (Prototype)map.get(key).clone(); //通过克隆方法创建的对象
     }
}

原型对象优缺点

优点

  1. 客户端针对抽象原型类进行编程,扩展性非常好
  2. 系统提高了创建相同或类似对象的效率
  3. 系统使用深克隆保存对象的状态,以便需要时使用,可辅助撤销操作
    缺点
  4. 每个类都配备一个克隆方法,修改产品需要修改源代码
  5. 当对象有嵌套引用时,每一层都要实现深克隆

原型模式适合场景

  1. 系统创建对象成本高,新对象可通过已有对象复制
  2. 系统需要保存对象的状态
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值