设计模式学习第五节 建造者模式

new复杂对象问题

    需求: 新建汽车对象,至少包含 大小、轮胎、装饰、发动机等等详细属性。最先想到的方式是直接new出对象。
    代码实现

package com.example.pattern.builder;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author zjt
 * @date 2020-12-11
 * 汽车对象
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Car {

    private Common common; // 通用属性

    private Tire tire; // 轮胎

    private Engine engine; // 发动机

    private Decorate decorate; // 装饰


}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Common {

    private String color; // 颜色

    private String model; // 型号

    private double length; // 长

    private double high; // 宽

    private double width; // 高
    // ......
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Tire {

    private String size;
    // ......

}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Engine {

    private String detail;
    // ......
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Decorate {

    private String seat;
    // ......
}
public static void main(String[] args) {
        Common common = new Common("白色", "V5", 5, 1.5, 2);
        Tire tire = new Tire("40CM");
        Engine engine = new Engine("8缸发动机");
        Decorate decorate = new Decorate("普通座椅");
        Car car = new Car(common, tire, engine, decorate);
        System.out.println(car);
    }

    这种方式的优点是容易理解、程序结构简单。缺点是没有设计缓存层,程序的扩展和维护不好,这种设计方案,把产品和创建产品的过程封装在一起,耦合性增加。解决思路:将产品和产品的创建过程进行解耦->建造者模式。

建造者模式

    基本介绍
    分离复杂对象的构建和表示,同样的构建过程可以创建不同的表示,
    1、建造者模式也叫做生成器模式,是一种对象构建模式。将复杂对象的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象。
    2、建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的用户构建细节。
    建造者模式的四个角色
    1、Product(产品角色):一个具体的产品对象。
    2、Builder(抽象建造者):创建一个Product对象的各个部件指定的接口/抽象类。
    3、ConcreteBuilder(具体建造者):实现接口,构建和装配各个部件。
    4、Director(指挥者):构建一个使用Builder接口的对象,它主要用户创建一个复杂的对象,它主要有两个作用,一:隔离了客户与对象的生产过程,二:负责控制产品对象的生产过程。
    类图分析
在这里插入图片描述

    变形之后代码实现

public interface CarBuilder { // 汽车构建器

    // 返回 CarBuilder 原因是调用是方便,可以写出链式调用的结构
    // 也可以返回 void 调用的时候会麻烦一点

    CarBuilder buildCommon(); // 构建通用信息

    CarBuilder buildTire(); // 构建轮胎信息

    CarBuilder buildEngine(); // 构建发动机信息

    CarBuilder buildDecorate(); // 构建装饰信息

    Car build(); // 返回汽车对象

}
public class MineCar implements CarBuilder {

    Car car = new Car();

    @Override
    public CarBuilder buildCommon() {
        car.common = new Common("白色", "ZL", 5, 1.6, 2.1);
        return this; // 返回当前对象
    }

    @Override
    public CarBuilder buildTire() {
        car.tire = new Tire("型号");
        return this;
    }

    @Override
    public CarBuilder buildEngine() {
        car.engine = new Engine("8缸发动机");
        return this;
    }

    @Override
    public CarBuilder buildDecorate() {
        car.decorate = new Decorate("真皮座椅");
        return this;
    }

    @Override
    public Car build() {
        return car;
    }
}

public class Client {

    public static void main(String[] args) {
        CarBuilder car = new MineCar();
        // 指挥者可以省略 使用链式调用初始化对象
        Car build = car.buildCommon()
                .buildEngine()
                .buildTire()
                .buildDecorate()
                .build();
        System.out.println(build);
    }
}

    构建者模式使用此方法构建抽象出去,也可以变形一下使用,类似于工厂模式。

@Data
@AllArgsConstructor
public class Car {

    public Common common; // 通用属性

    public Tire tire; // 轮胎

    public Engine engine; // 发动机

    public Decorate decorate; // 装饰
    
    // ......

    private Car() { // 私有化构造器
    }

    public static class CarBuilder { // 内部静态类统一构建Car对象 类似于静态工厂
        Car car = new Car();

        public CarBuilder commonInfo(String color, String model, double length, double high, double width) {
            car.common = new Common(color, model, length, high, width);
            return this;
        }

        public CarBuilder tireInfo(String size) {
            car.tire = new Tire(size);
            return this;
        }

        public CarBuilder engineInfo(String detail) {
            car.engine = new Engine(detail);
            return this;
        }

        public CarBuilder decorateInfo(String seat) {
            car.decorate = new Decorate(seat);
            return this;
        }

        public Car build() {
            return car;
        }
    }
}
        Car car1 = new Car.CarBuilder()
        		.commonInfo("1", "1", 1, 1, 1)
                .tireInfo("1")
                .engineInfo("1")
                //.decorateInfo("1") 用到的传入,用不到的不传值
                .build();
        System.out.println(car1);

    建造者模式的注意事项和细节
    1、客户端(使用程序)无需知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
    2、每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。
    3、可以更加精细的控制产品的创建过程,将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方法使用程序来控制创建过程。
    4、增加新的具体建造者无需修改原有类库的代码,指挥者针对抽象建造者类进行编程,系统扩展方便,符合开闭原则。
    5、建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
    6、如果产品的内部变化复杂,可能会导致需要定义很多的具体建造者来实现这种变化,导致系统代码变得庞大,因此在这种情况下需要考虑是否选择建造者模式。
    7、抽象工厂模式与建造者模式:抽象工厂模式实现对产品家族的定义,一个产品家族是这样一系列的产品,具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可。建造者模式则要求按照指定的蓝图构建产品,它的主要目的是通过组装零配件而产生一个新的产品。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值