• 建造者模式(Builder)


    什么是建造者模式

    建造者模式,将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

    它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成。它将变与不变相分离,即产品的组成部分是不变的,但每一部分是可以灵活选择的。

    如:计算机由CPU、内存、主板、硬盘、电源等组成,组成计算机都有这些部分 但各个部分都是可以灵活选择的。下面的例子就是不同的建造者用不同的方法制造了华为电脑和苹果电脑。
    再比如,用仅用木头(木门、木墙、木顶)建造木头房子,用石头建造石头(石门、石墙、石顶)房子。
    电脑是产品,房子也是产品。他们的组成 生产过程基本一致,但构成的各个部分不同,通过不同的建造者完成不同产品的建造。

    下面结合具体实例更好理解。

    建造者模式也是一种创建型模式。

    适用场景

    建造者(Builder)模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定, 所以它通常在以下场合使用。

    • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
    • 当需要使用代码创建不同形式的产品。如果你需要创建的各种形式的产品,它们的制造过程相似且主要有细节上的差异。

    优缺点

    优点:
    具体建造者相互独立,易于扩展,生成不同形式的产品。
    客户端不必知道产品内部组成的细节,便于控制细节风险。
    可以分步骤(或分部分)构造对象。

    缺点:
    产品的组成部分必须相同,限制了其使用范围。
    如果产品的内部变化复杂,会增加很多的建造者类。

    组成角色

    建造者(Builder)模式由产品、抽象建造者、具体建造者、指挥者 4 个角色构成。

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

    实现说明

    实现主要考虑的:
    1.首先清晰 所有形式的产品,他们不变的地方,有哪些通用的步骤或者组成部分。生成产品角色。
    2.在抽象建造者中 声明 这些步骤或组成部分。
    3.为每个形式的产品,创建具体的建造者,并实现构造步骤或各个组成部分。
    4.创建指挥者。
    5.客户端代码会同时创建建造者对象和指挥者对象。客户端创建Director对象,并用它所想要的Builder对象进行配置。

    建造者模式和抽象工厂模式的关注点不同:建造者模式注重零部件的组装过程(即如何分步骤/分部分的生成复杂对象),而抽象工厂专门用于生产一系列相关对象,但两者可以结合使用。
    抽象工厂模式会马上返回产品, 建造者模式则允许你在获取产品前执行一些额外构造步骤。

    实例 demo

    根据上面的四种角色。下面的demo就是:电脑是产品;2个具体建造者分别建造华为电脑和苹果电脑;指挥者通过建造者获得不同的产品。

    产品角色(Product):这里的产品就是电脑,它由cpu、内存、主板等构成。

    public class ComputerProduct {
        private String cpu;
        private String memory;
        private String board;
        
        public void setCpu(String cpu) {
            this.cpu = cpu;
        }
        
        public void setMemory(String memory) {
            this.memory = memory;
        }
        
        public void setBoard(String board) {
            this.board = board;
        }
        
        public String show() {
            return this.cpu+";
    "+this.memory+";
    "+this.board+";
    ";
        }
    }
    

    抽象建造者(Builder):提供接口,分别创建cpu、内存、主板。

    public interface ComputerBuilder {
        void buildCpu();
        void buildMemory();
        void buildBoard();
        
        //产品对象
        ComputerProduct computerProduct = new ComputerProduct();
    }
    

    具体建造者(Concrete Builder):这里提供了2队建造者,分别生产华为电脑、苹果电脑。各个建造者单独实现各自产品的各个部件。

    public class HuaWeiComputerBuilder implements ComputerBuilder {
    
        @Override
        public void buildCpu() {
            computerProduct.setCpu("MateBook X Pro CPU:i7-10510U");
        }
    
        @Override
        public void buildMemory() {
            computerProduct.setMemory("MateBook X Pro Memory:LPDDR3 2133MHz 16GB");
        }
    
        @Override
        public void buildBoard() {
            computerProduct.setBoard("MateBook X Pro Board:HuaWei");
        }
    
    }
    
    public class AppleComputerBuilder implements ComputerBuilder {
    
        @Override
        public void buildCpu() {
            computerProduct.setCpu("MacBook Pro 13 CPU:Intel Core i5");
        }
    
        @Override
        public void buildMemory() {
            computerProduct.setMemory("MacBook Pro 13 Memory:8GB 2133MHz LPDDR3");
        }
    
        @Override
        public void buildBoard() {
            computerProduct.setBoard("MacBook Pro 13 Board:Apple");
        }
    
    }
    

    指挥者(Director):通过Builder接口的对象完成复杂对象的构建,生成产品。不关注具体产品生产过程,具体产品生产由对应具体建造者完成。

    public class ComputerDirector {
        public ComputerProduct buildComputer(ComputerBuilder computerBuilder) {
            computerBuilder.buildCpu();
            computerBuilder.buildMemory();
            computerBuilder.buildBoard();
            return computerBuilder.computerProduct;
        }
    }
    

    客户端调用demo:分别生产华为电脑 和 苹果电脑。

    public class ClientTest {
        public static void main(String[] args) {
            ComputerDirector computerDirector = new ComputerDirector();
            ComputerProduct huaweiComputer = computerDirector.buildComputer(new HuaWeiComputerBuilder());
            System.out.println(huaweiComputer.show());
            
            ComputerProduct appleComputer = computerDirector.buildComputer(new AppleComputerBuilder());
            System.out.println(appleComputer.show()); 
        }
    }
    

    执行结果:

    MateBook X Pro CPU:i7-10510U;
    MateBook X Pro Memory:LPDDR3 2133MHz 16GB;
    MateBook X Pro Board:HuaWei;
    
    MacBook Pro 13 CPU:Intel Core i5;
    MacBook Pro 13 Memory:8GB 2133MHz LPDDR3;
    MacBook Pro 13 Board:Apple;
    
  • 相关阅读:
    StringBuider 在什么条件下使用效率更高?
    Hibernate 与 Mybatis 如何共存?打破你的认知!
    牛逼!OpenJDK 源码要迁移到 GitHub 了!
    别在网上乱找代码了,找了一段代码突然爆了!!!
    8 条关于 Web 前端性能的优化建议
    关于 equals 和 hashCode,看这一篇真的够了!
    Python web之Python如何调用REST服务?
    ArcGIS Server如何发布gp服务
    ArcGIS坐标单位转换(米和度分秒之间是如何转换的?)
    ArcGIS MapServer和FeatureServer的区别
  • 原文地址:https://www.cnblogs.com/fanglongxiang/p/13211339.html
Copyright © 2020-2023  润新知