谈谈设计模式:建造者模式在jdk中的体现,它和工厂模式区别?

createh52周前 (04-21)技术教程7

背景

建造模式(Builder模式)

假如有一个需求:盖房子,盖房子过程是一致的:打桩、砌墙、封顶。但是房子是各式各样的,最后盖出来的房子可能是高楼或别墅。

根据直接的思路,不用设计模式思想,我们也许会:

  1. 写一个 CommonHouse 抽象类,然后里面规定了打桩、砌墙、封顶三个方法;
  2. 让不同房子继承这个类;
  3. 最后调用的时候调用分别的方法即可。

在继承抽象类、子类区分这一块,思想没有问题,问题出现这些类本身。

缺点:

过于简单,将产品(房子)和创建产品(房子建造流程)封装在了一起,耦合性增强了。(可以理解为,面向对象的思想里,房子虽然是一个类,拥有自己的方法,但是房子不应该拥有建造自己的方法)

解决方法:

解耦 - > 建造者模式。

一、建造者模式

建造者模式(Builder Pattern)又叫生成器模式,是一种对象构建模式(创建型),可以将复杂对象的建造过程抽象出来(抽象类),使这个抽象过程的不同实现方法能构造出不同表现(属性)的对象。

建造模式允许用户只通过指定复杂对象的类型和内容就可以构建他们,用户不需要知道内部的具体构建细节。

建造者模式的四个角色:

  1. Product产品:一个具体产品对象;
  2. Builder(抽象建造者):创建Product对象指定的 接口或者抽象类;
  3. ConcreteBuilder具体建造者:实现接口,构建和装配各个部件;
  4. Director指挥者:构建一个使用Builder接口的对象,主要用于创建一个复杂度对象,有两个作用:一是隔离客户与对象的生产过程,二是负责控制产品对象的生产过程。

他们之间的关系,我们用类图来解释:

  • Directer里面聚合一个Builder实际上使用的是他的实现类ConcreteBuilder;
  • ConcreteBuilder可以有很多,就是所谓的不同的房子的建造者。

因为getRusult是一样的,所以暂时不用接口,用抽象类实现Builder,代码如下:

/*
    产品,对应product
*/
public class House {
    private String base;
    private String wall;
    private String roof;
    //对应getset方法
}
/*
    抽象的建造者,对应Builder
*/
public abstract class HouseBuilder {
    protected House house = new House();
    //写好流程的各个方法,但不约束具体执行
    public abstract void buildBasic();
    public abstract void buildWalls();
    public abstract void buildRoof();
    //建造方法,返回建造结果
    public House buildHouse(){
        return house;
    }
}
/*
    普通房子制造流程,继承抽象类
    可以看到,制造流程在这里,而House类拥有房子的属性,他们是分开的
    应是对House的操作,这里省略
*/
public class CommonHouse extends HouseBuilder{
    @Override
    public void buildBasic() {
        System.out.println("普通房子:建造地基。。。");
    }
    @Override
    public void buildWalls() {
        System.out.println("普通房子:砌墙。。。");
    }
    @Override
    public void buildRoof() {
        System.out.println("普通房子:盖屋顶。。。");
    }
}
/*
    另一个实现类,本来应是对House的操作,这里省略
*/
public class HighHouse extends HouseBuilder {
    @Override
    public void buildBasic() {
        System.out.println("高楼:建造地基。。。");
    }
    @Override
    public void buildWalls() {
        System.out.println("高楼:砌墙。。。");
    }
    @Override
    public void buildRoof() {
        System.out.println("高楼:盖屋顶。。。");
    }
}
/*
    Director,聚合建造者HouseBuilder
    同时决定制作流程,最后调用建造者的buildHouse方法返回
*/
public class Director {
    HouseBuilder houseBuilder = null;
    //通过构造器聚合
    public Director(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }
    //通过setter方法聚合
    public void setHouseBuilder(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }
    //指挥具体建造流程,先后顺序不由Builder决定
    public House constructHouse(){
        houseBuilder.buildBasic();
        houseBuilder.buildWalls();
        houseBuilder.buildRoof();
        return houseBuilder.buildHouse();
    }
}
/*
    客户端
*/
public class Client {
    public static void main(String[] args) {
        //new房子
        CommonHouse commonHouse = new CommonHouse();
        //new指挥者
        Director director = new Director(commonHouse);
        //完成盖房
        House house = director.constructHouse();

        //重置建造者
        HighHouse highHouse = new HighHouse();
        director.setHouseBuilder(highHouse);
        House house1 = director.constructHouse();
    }
}

上面代码总结起来:一是要把房子归为房子,有属性就够了,建造归建造,相当于是建筑工人,和房子两个对象分开,那么Director相当于包工头,对于不同的House要指挥不一样的Builder群体。

二、建造者模式在JDK中的应用

java.lang.StringBuilder类,也就是常用的可变字符串类,用到的就是建造者模式。以其中的常用方法 append 方法为例看源码。

2.1 Appendable 接口

定义了多个 append 方法(抽象方法),即 Appendable 就是我们的抽象建造者Builder 。

2.2 具体的实现类 AbstractStringBuilder

虽然也是一个抽象类,但是也已经实现了 Append able 接口的方法,所以其实相当于是具体的建造者ConcreteBuilder了;

2.3 StringBuilder,继承了AbstractStringBuilder

但是他重写 append 方法的方式只是调用了父类方法,所以应该说,StringBuilder既充当了Director,又是一个ConcreteBuilder.

三、注意事项

  1. 客户端不必知道产品呢内部组成的细节,将产品本身和产品的创建过程解耦,使得相同的创建过程可以创建不同的产品;
  2. 每一个具体的建造者都是相对独立的,和其他的建造者无关,因此可以方便替换具体建造者或者增加新的具体建造者,用户使用不同的具体建造者就能得到不同产品;
  3. 可以更加精细的控制创建过程;
  4. 增加新的具体建造者无需修改原有代码,指挥者针对抽象建造者编程;
  5. 建造者模式创建的产品,一定是共同点比较多,组成部分相似,如果产品之间的差异性很大,那么就不适合使用建造者模式,因此其适用范围受到一定的限制。

建造者模式 VS 抽象工厂模式:

抽象工厂模式实现对产品家族的创建,一个产品家族:具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产。

建造者模式是按照指定的要求创造产品,主要目的是通过组装零件产生一个新产品。

相关文章

Java设计模式:工厂模式与抽象工厂模式深度解读

Java设计模式:工厂模式与抽象工厂模式深度解读在Java的世界里,设计模式是解决常见软件设计问题的一套经过验证的解决方案。其中,工厂模式和抽象工厂模式是创建型模式的两大支柱,它们就像建筑工地上的“预...

Java工厂方法模式详解:从流水线到代码的智慧

一、现实中的工厂启示场景1:汽车制造假设某汽车公司有多个分厂:o 北京分厂:生产燃油车o 上海分厂:生产电动车o 广州分厂:生产混动车总部的生产规范手册规定:1. 所有分厂必须实现生产汽车()方法2....

JAVA设计模式深度解读:工厂模式与抽象工厂模式的差异

JAVA设计模式深度解读:工厂模式与抽象工厂模式的差异在软件开发的世界里,设计模式就像烹饪界的食谱,它们指导我们如何构建系统以提高可维护性和扩展性。今天,我们将聚焦于两种经典的创建型设计模式——工厂模...

Java抽象工厂模式解析:原理、案例与最佳实践

一、模式说明抽象工厂模式(Abstract Factory Pattern)是创建型设计模式的集大成者,通过提供对象创建的抽象接口,让具体工厂类负责生产一组相关或相互依赖的对象。该模式强调"产...

简单工厂模式详解:优缺点、实现步骤、以及应用场景全面总结

简单工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,这种类型的设计模式属于创建型模式。本文从一个具体的例子逐步分析,来体会简单工厂模式的应用场景和利弊@mikechen...

Java 中使用泛型实现工厂模式

概述在本文中,我们将学习如何在 Java 中使用泛型实现工厂模式。什么是工厂模式?在面向对象编程中,工厂模式是一种创建型设计模式,在被调用时创建对象。工厂是一个在工厂方法被调用时创建原型类(也称为接口...