设计模式-建造者模式

设计模式

设计模式的本质是面向对象设计原则的实际运用,是对类的==封装性==、==继承性==和==多态性==以及类的关联关系和组合关系的充分理解。

创建型模式-建造者模式

定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。
eg: 汽车中的方向盘、发动机、车架、轮胎等部件组装,计算机由 CPU、主板、内存、硬盘、显卡、机箱、显示器、键盘、鼠标等部件组装。

特点:

  • 封装性好,构建和表示分离。
  • 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
  • 客户端不必知道产品内部组成的细节

缺点:

  • 产品的组成部分必须相同,适用产品范围被限制
  • 如果产品内部发生变化,则建造者也要同步修改,变化较为复杂,维护成本大

结构

建造者(==Builder==)模式由产品、抽象建造者、具体建造者、指挥者等 4 个要素构成

主要角色说明:

  • 产品角色(==Product==):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个零部件。
  • 抽象建造者(==Builder==):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
  • 具体建造者(==Concrete Builder==):实现 ==Builder== 接口,完成复杂产品的各个部件的具体创建方法。
  • 指挥者(==Director==):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

UML 类图关系

image

建造者模式的实际体现

JDK

StringBuilder:

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
    
    @Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

    @Override
    public StringBuilder append(CharSequence s) {
        super.append(s);
        return this;
    }

    @Override
    public StringBuilder append(char[] str) {
        super.append(str);
        return this;
    }
    ...
}

AbstractStringBuilder:

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
}

Appendable:

public interface Appendable {
    Appendable append(CharSequence csq) throws IOException;
    Appendable append(CharSequence csq, int start, int end) throws IOException;
    Appendable append(char c) throws IOException;
}
  • Appendable定义多个 append() 抽象方法,抽象建造者
  • AbstractStringBuilder 实现 Appendable 接口,已经作为了建造者,只是抽象类不能直接实例化,通过 StringBuilder 子类进行实例化。
  • StringBuilder 继承 AbstractStringBuilder ,即作为具体建造者,也作为指挥者。

Spring

BeanDefinitionBuilder:

public final class BeanDefinitionBuilder {
    
    public AbstractBeanDefinition getRawBeanDefinition() {
        return this.beanDefinition;
    }
    ...
    public BeanDefinitionBuilder setParentName(String parentName) {
        this.beanDefinition.setParentName(parentName);
        return this;
    }
    
    public BeanDefinitionBuilder setFactoryMethod(String factoryMethod) {
        this.beanDefinition.setFactoryMethodName(factoryMethod);
        return this;
    }

    public BeanDefinitionBuilder setScope(String scope) {
        this.beanDefinition.setScope(scope);
        return this;
    }

    ...
        
    public BeanDefinitionBuilder addPropertyValue(String name, Object value) {
        this.beanDefinition.getPropertyValues().add(name, value);
        return this;
    }
    ...
}

AbstractBeanDefinition:

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
        implements BeanDefinition, Cloneable {
    
    protected AbstractBeanDefinition(BeanDefinition original) {
        setParentName(original.getParentName());
        setBeanClassName(original.getBeanClassName());
        setScope(original.getScope());
        setAbstract(original.isAbstract());
        setFactoryBeanName(original.getFactoryBeanName());
        setFactoryMethodName(original.getFactoryMethodName());
        setRole(original.getRole());
        setSource(original.getSource());
        copyAttributesFrom(original);
        ...
    }
}

BeanDefinition:

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
    void setParentName(String parentName);
    void setFactoryMethod(String factoryMethod);
    void setFactoryMethodOnBean(String factoryMethod, String factoryBean);
    void addConstructorArgValue(@Nullable Object value);
    void addConstructorArgReference(String beanName);
    void addPropertyValue(String name, @Nullable Object value);
}
  • BeanDefinition 扮演抽象 ==Builder== 的角色
  • BeanDefinitionBuilder 扮演具体 ==Builder== 角色
  • AbstractBeanDefinition 既扮演指挥者角色又为 ==Product==

简单使用示例

创建角色

  • Director

    public class Director {
    
        private Builder builder;
    
        public Director(Builder builder) {
            this.builder = builder;
        }
    
        public Computer construct(String cpu, String motherboard, String graphic) {
            builder.cpu(cpu);
            builder.motherboard(motherboard);
            builder.graphic(graphic);
            builder.os();
            return builder.build();
        }
    }
    
  • Builder

    public abstract class Builder {
    
        /**
         * setupCPU
         * @param cpu
         */
        public abstract void cpu(String cpu);
    
        /**
         * setupMotherboard
         * @param motherboard
         */
        public abstract void motherboard(String motherboard);
    
        /**
         * setupGraphic
         * @param graphic
         */
        public abstract void graphic(String graphic);
    
        /**
         * setOS
         */
        public abstract void os();
    
        /**
         * build
         * @return
         */
        public abstract Computer build();
    }
    
  • LenovoLaptopBuilder

    public class LenovoLaptopBuilder extends Builder {
    
        private Computer computer = new Computer();
    
        @Override
        public void cpu(String cpu) {
            computer.setCpu(cpu);
        }
    
        @Override
        public void motherboard(String motherboard) {
            computer.setMotherboard(motherboard);
        }
    
        @Override
        public void graphic(String graphic) {
            computer.setGraphic(graphic);
        }
    
        @Override
        public void os() {
            computer.setOs("Windows 10");
        }
    
        @Override
        public Computer build() {
            return computer;
        }
    }
    
  • MacLaptopBuilder

    public class MacLaptopBuilder extends Builder{
    
        private Computer computer = new Computer(); 
        
        @Override
        public void cpu(String cpu) {
            computer.setCpu(cpu);
        }
    
        @Override
        public void motherboard(String motherboard) {
            computer.setMotherboard(motherboard);
        }
    
        @Override
        public void graphic(String graphic) {
            computer.setGraphic(graphic);
        }
    
        @Override
        public void os() {
            computer.setOs("MacOS");
        }
    
        @Override
        public Computer build() {
            return computer;
        }
    }
    
  • Computer

    public class Computer {
        
        private String cpu;
        private String motherboard;
        private String graphic;
        private String os;
    
        public void setCpu(String cpu) {
            this.cpu = cpu;
        }
    
        public void setMotherboard(String motherboard) {
            this.motherboard = motherboard;
        }
    
        public void setGraphic(String graphic) {
            this.graphic = graphic;
        }
    
        public void setOs(String os) {
            this.os = os;
        }
    }
    

简化模式

将角色==Director==与==Client==共用,以达到一种链式调用的编程

  • Laptop

    public class Laptop {
        private String cpu;
        private String motherboard;
        private String graphic;
        private String os;
    
        public String getCpu() {
            return cpu;
        }
    
        public void setCpu(String cpu) {
            this.cpu = cpu;
        }
    
        public String getMotherboard() {
            return motherboard;
        }
    
        public void setMotherboard(String motherboard) {
            this.motherboard = motherboard;
        }
    
        public String getGraphic() {
            return graphic;
        }
    
        public void setGraphic(String graphic) {
            this.graphic = graphic;
        }
    
        public String getOs() {
            return os;
        }
    
        public void setOs(String os) {
            this.os = os;
        }
    
        public Laptop(String cpu, String motherboard, String graphic, String os) {
            this.cpu = cpu;
            this.motherboard = motherboard;
            this.graphic = graphic;
            this.os = os;
        }
    
            /**
         * 静态工厂方法构建 Builder
         * @return
         */
        public static Laptop.Builder builder() {
            return new Laptop.Builder();
        }
    
            /**
         * 静态内部类
         */
        public static class Builder {
            private String cpu;
            private String motherboard;
            private String graphic;
            private String os;
    
            public Laptop.Builder cpu(String cpu) {
                this.cpu = cpu;
                return this;
            }
    
            public Laptop.Builder motherboard(String motherboard) {
                this.motherboard = motherboard;
                return this;
            }
    
            public Laptop.Builder graphic(String graphic) {
                this.graphic = graphic;
                return this;
            }
    
            public Laptop.Builder os(String os) {
                this.os = os;
                return this;
            }
    
            public Laptop build() {
                return new Laptop(cpu, motherboard, graphic, os);
            }
        }
    
        public static void main(String[] args) {
        Laptop laptop = Laptop.builder()
                      .cpu("intel")
                      .motherboard("apple")
                      .graphic("amd")
                      .os("macOS")  
                      .build();
            System.out.println(laptop);
        }
    }
    
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 建造者模式:将一个复杂对象的构建与它的表示分离,是的同样的构建过程可以创建不同的表示 使用建造者模式,客户端只需要...
    超级大鸡腿阅读 217评论 0 0
  • 设计模式-建造者模式 概念 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示 用户只需指定...
    蜗牛写java阅读 242评论 0 0
  • 1.简介 将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。 2.使用场景 主要解决在软件系统...
    夜沐下的星雨阅读 135评论 0 0
  • 英文:Builder 对于建造者模式而已,它主要是将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的...
    代码之尖阅读 560评论 0 51
  • 我的博客地址 建造者模式 主要参考了 /冰鉴/ 的一篇博客,觉得写的很详细,然后自己敲了一遍。学习了 设计模式之建...
    下位子阅读 480评论 2 6