美文网首页
建造者模式

建造者模式

作者: jianshujoker | 来源:发表于2020-04-09 08:46 被阅读0次

定义

将一个复杂对象的构建与表示分离,同样的构建过程创建不同的表示

  • 构建:有些情况,一个对象的性质必须依赖于某个顺序赋值才有意义,这使得构建对象具有复杂的逻辑,因此,这个构建过程可以被外部化到一个叫建造者的对象里,建造者将构建好的产品返回给客户端
  • 表示:一个产品有不同的组成部分,不同的产品有不同的组成部分,建造者模式使得客户端不用知道所生产的产品有哪些部分,有什么差异,是怎么构建出来的。就像房子,买房者得到的是修建好的房子,而不用关心房子是怎么建造好的

应用场景

  • 产品较复杂,需要赋值的属性不一时
  • 多个部件或零件都可以装配到一个对象上,但产生的结果不同
  • 产品类中的调用顺序不同产生不同的结果

常用写法

标准写法

  • 产品
/**
 * 产品
 */
@Data
public class Product {
    /**
     * 需要建造的A部分
     */
    private String partA;

    /**
     * 需要建造的B部分
     */
    private String partB;
}
  • 建造者接口
/**
 * 建造者接口,定义行为
 */
public interface IBuilder {
    /**
     * 建造A部分
     */
    void buildPartA();

    /**
     * 建造B部分
     */
    void buildPartB();

    /**
     * 给出建造好的产品
     */
    Product build();
}
  • 实际的建造者
/**
 * 实际的建造者,当只有一个建造者的时候,通常会省去IBuilder的定义
 */
public class ConcreteBuilder implements IBuilder {
    private Product product = new Product();

    @Override
    public void buildPartA() {
        product.setPartA("A");
    }

    @Override
    public void buildPartB() {
        product.setPartB("B");
    }

    @Override
    public Product build() {
        return product;
    }
}
  • 指挥者、调用者
/**
 * 指挥者,负责产品部分完整建造或按顺序创建,就像建造房子时,施工队不和客户交流,而是有个管理者
 * 指挥先建地基,后建房子,然后装修,最后交出建造好的房子给客户一样
 */
public class Director {
    public static void main(String[] args) {
        IBuilder builder = new ConcreteBuilder();
        builder.buildPartA();
        builder.buildPartB();
        Product product = builder.build();
    }
}
  • 类图


    建造者模式标准写法.png

lombock builder

  • 原始代码
import lombok.Builder;
import lombok.Data;
/**
 * 产品
 */
@Builder
@Data
public class Product {
    /**
     * 需要建造的A部分
     */
    private String partA;

    /**
     * 需要建造的B部分
     */
    private String partB;
}
  • lombock 实际构建的builder
public class Product {
    private String partA;
    private String partB;

    Product(final String partA, final String partB) {
        this.partA = partA;
        this.partB = partB;
    }

    public static Product.ProductBuilder builder() {
        return new Product.ProductBuilder();
    }

    public String getPartA() {
        return this.partA;
    }

    public String getPartB() {
        return this.partB;
    }

    public void setPartA(final String partA) {
        this.partA = partA;
    }

    public void setPartB(final String partB) {
        this.partB = partB;
    }

    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Product)) {
            return false;
        } else {
            Product other = (Product)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                Object this$partA = this.getPartA();
                Object other$partA = other.getPartA();
                if (this$partA == null) {
                    if (other$partA != null) {
                        return false;
                    }
                } else if (!this$partA.equals(other$partA)) {
                    return false;
                }

                Object this$partB = this.getPartB();
                Object other$partB = other.getPartB();
                if (this$partB == null) {
                    if (other$partB != null) {
                        return false;
                    }
                } else if (!this$partB.equals(other$partB)) {
                    return false;
                }

                return true;
            }
        }
    }

    protected boolean canEqual(final Object other) {
        return other instanceof Product;
    }

    public int hashCode() {
        int PRIME = true;
        int result = 1;
        Object $partA = this.getPartA();
        int result = result * 59 + ($partA == null ? 43 : $partA.hashCode());
        Object $partB = this.getPartB();
        result = result * 59 + ($partB == null ? 43 : $partB.hashCode());
        return result;
    }

    public String toString() {
        return "Product(partA=" + this.getPartA() + ", partB=" + this.getPartB() + ")";
    }

    public static class ProductBuilder {
        private String partA;
        private String partB;

        ProductBuilder() {
        }

        public Product.ProductBuilder partA(final String partA) {
            this.partA = partA;
            return this;
        }

        public Product.ProductBuilder partB(final String partB) {
            this.partB = partB;
            return this;
        }

        public Product build() {
            return new Product(this.partA, this.partB);
        }

        public String toString() {
            return "Product.ProductBuilder(partA=" + this.partA + ", partB=" + this.partB + ")";
        }
    }
}
  • 使用lombok的builder的好处
    • 方便:只需要加一个@Builder,隐去了director和Ibuilder,帮助创建实际的建造者ProductBuilder,而不需要自己写
    • 链式构建对象,不用一个一个去set

优缺点

优点

  • 封装性好,创建和使用分离
  • 扩展性好,建造类之间独立

缺点

  • 产生多余的对象
  • 产品改变时,建造者也需要一起跟着变

相关文章

  • Builder Pattern in Java

    建造者模式:建造者模式定义建造者模式应用场景实现案例Jdk中的建造者模式建造者模式的优点建造者模式的缺点 建造者模...

  • 设计模式(4) 建造者模式

    什么是建造者模式 经典建造者模式的优缺点 对建造者模式的扩展 什么是建造者模式 建造者模式将一个复杂的对象的构建与...

  • 建造者模式(部件构造)

    目录 建造者模式的理念 从 POJO 到建造者模式的思考 怎么来实现建造者模式 建造者模式在Android源码中的...

  • 【设计模式】之建造者Builder模式

    建造者模式 什么是建造者模式? 建造者模式属于创建型模式的一员,可以控制对象的实例化过程。建造者模式简化了复杂对象...

  • 建造者模式

    一、建造者模式介绍 二、建造者模式代码实例

  • 建造者模式

    建造者模式 首先,建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和...

  • 建造者模式:深入理解建造者模式 ——组装复杂的实例

    目录: 一 建造者模式介绍 1.1 定义 1.2 为什么要用建造者模式(优点)? 1.3 哪些情况不要用建造者模式...

  • 设计模式之建造者模式

    设计模式之建造者模式 Intro 简介 建造者模式: 建造者模式隐藏了复杂对象的创建过程,它把复杂对象的创建过程加...

  • 一、设计模式(构建模式)——03建造模式与原型模式

    建造者模式 建造型模式用于创建过程稳定,但配置多变的对象。 建造模式的实现要点: 在建造者模式中,指挥者是直接与客...

  • 创建型模式:建造者模式

    个人公众号原文:创建型模式:建造者模式 五大创建型模式之四:建造者模式。 简介 姓名 :建造者模式 英文名 :Bu...

网友评论

      本文标题:建造者模式

      本文链接:https://www.haomeiwen.com/subject/jshqmhtx.html