• 09 创建型模式-建造者模式


    1.建造者模式介绍:

    建造者模式 (builder pattern), 也被称为生成器模式 , 是一种创建型设计模式
    定义: 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不
    同的表示。

    2.建造者模式要解决的问题

    建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象。用
    户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构
    造细节。
    在这里插入图片描述

    3 建造者模式原理

    在这里插入图片描述
    在这里插入图片描述

    3.1 建造者模式实现方式1
    创建共享单车

    在这里插入图片描述
    在这里插入图片描述

    具体产品
    /**
     * 自行车类
     **/
    public class Bike {
    
        private String frame; //车架
    
        private String seat; //车座
    
        public String getFrame() {
            return frame;
        }
    
        public void setFrame(String frame) {
            this.frame = frame;
        }
    
        public String getSeat() {
            return seat;
        }
    
        public void setSeat(String seat) {
            this.seat = seat;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    /**
     * 抽象建造者类
     **/
    public abstract class Builder {
    	//申明一个protect对象给子类使用
        protected Bike mBike = new Bike();
    
        public abstract void buildFrame();
    
        public abstract void buildSeat();
    
        public abstract Bike createBike();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    /**
     * 摩拜单车建造者
     **/
    public class MobikeBuilder extends Builder {
    
        @Override
        public void buildFrame() {
            System.out.println("制作车架!");
            mBike.setFrame("铝合金车架");
        }
    
        @Override
        public void buildSeat() {
            System.out.println("制作车座");
            mBike.setSeat("真皮车座");
        }
    
        @Override
        public Bike createBike() {
            return mBike;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    /**
     * 哈罗单车建造者	
     **/
    public class HelloBikeBuilder  extends Builder{
    
        @Override
        public void buildFrame() {
            System.out.println("制作碳纤维车架");
            mBike.setFrame("碳纤维车架");
        }
    
        @Override
        public void buildSeat() {
            System.out.println("制作橡胶车座");
            mBike.setFrame("橡胶车座");
        }
    
        @Override
        public Bike createBike() {
            return mBike;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    指挥者类
    /**
     * 指挥者类
     **/
    public class Director {
    
        private Builder mBuilder;
    
        public Director(Builder mBuilder) {
            this.mBuilder = mBuilder;
        }
    
    
        //自行车制作方法
        public Bike construct(){
            mBuilder.buildFrame();
            mBuilder.buildSeat();
            return mBuilder.createBike();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    /**
     * 客户端
     **/
    public class Client {
    
        public static void main(String[] args) {
    
            //1.创建指挥者
            Director director = new Director(new MobikeBuilder());
    
            //2.获取自行车
            Bike bike = director.construct();
            System.out.println(bike.getFrame() + "," + bike.getSeat());
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    3.2建造者模式实现方式2

    在这里插入图片描述

    /**
     * MQ连接客户端
     **/
    public class RabbitMQClient1 {
    
        private String host = "127.0.0.1";
    
        private int port = 5672;
    
        private int mode;
    
        private String exchange;
    
        private String queue;
    
        private boolean isDurable = true;
    
        int connectionTimeout = 1000;
    
        public RabbitMQClient1(String host, int port, int mode, String exchange, String queue, boolean isDurable, int connectionTimeout) {
            this.host = host;
            this.port = port;
            this.mode = mode;
            this.exchange = exchange;
            this.queue = queue;
            this.isDurable = isDurable;
            this.connectionTimeout = connectionTimeout;
    
            if(mode == 1){ //工作队列模式不需要设计交换机,但是队列名称一定要有
                if(exchange != null){
                    throw new RuntimeException("工作队列模式无需设计交换机");
                }
                if(queue == null || queue.trim().equals("")){
                    throw new RuntimeException("工作队列模式名称不能为空");
                }
                if(isDurable == false){
                    throw new RuntimeException("工作队列模式必须开启持久化");
                }
            }else if(mode == 2){ //路由模式必须设计交换机,但是不能设计队列
                if(exchange == null){
                    throw new RuntimeException("路由模式下必须设置交换机");
                }
                if(queue != null){
                    throw new RuntimeException("路由模式无须设计队列名称");
                }
            }
    
            //其他验证方式,
        }
    
        public void sendMessage(String msg){
    
            System.out.println("发送消息......");
        }
    
        public static void main(String[] args) {
            //每一种模式,都需要根据不同的情况进行实例化,构造方法会变得过于复杂.
            RabbitMQClient1 client1 = new RabbitMQClient1("192.168.52.123",5672,
                    2,"sample-exchange",null,true,5000);
    
            client1.sendMessage("Test-MSG");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    在这里插入图片描述

    /**
     * MQ连接客户端
     **/
    public class RabbitMQClient2 {
    
        private String host = "127.0.0.1";
        private int port = 5672;
        private int mode;
        private String exchange;
        private String queue;
        private boolean isDurable = true;
        int connectionTimeout = 1000;
        //私有化构造方法
        private RabbitMQClient2() {}
    
        public String getExchange() {
            return exchange;
        }
    
        public void setExchange(String exchange) {
    
            if(mode == 1){ //工作队列模式不需要设计交换机,但是队列名称一定要有
                if(exchange != null){
                    throw new RuntimeException("工作队列模式无需设计交换机");
                }
                if(queue == null || queue.trim().equals("")){
                    throw new RuntimeException("工作队列模式名称不能为空");
                }
                if(isDurable == false){
                    throw new RuntimeException("工作队列模式必须开启持久化");
                }
            }else if(mode == 2){ //路由模式必须设计交换机,但是不能设计队列
                if(exchange == null){
                    throw new RuntimeException("路由模式下必须设置交换机");
                }
                if(queue != null){
                    throw new RuntimeException("路由模式无须设计队列名称");
                }
            }
    
            //其他验证方式,
    
            this.exchange = exchange;
        }
    
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        public int getMode() {
            return mode;
        }
    
        public void setMode(int mode) {
    
            if(mode == 1){ //工作队列模式不需要设计交换机,但是队列名称一定要有
                if(exchange != null){
                    throw new RuntimeException("工作队列模式无需设计交换机");
                }
                if(queue == null || queue.trim().equals("")){
                    throw new RuntimeException("工作队列模式名称不能为空");
                }
                if(isDurable == false){
                    throw new RuntimeException("工作队列模式必须开启持久化");
                }
            }else if(mode == 2){ //路由模式必须设计交换机,但是不能设计队列
                if(exchange == null){
                    throw new RuntimeException("路由模式下必须设置交换机");
                }
                if(queue != null){
                    throw new RuntimeException("路由模式无须设计队列名称");
                }
            }
    
            this.mode = mode;
        }
    
        public String getQueue() {
            return queue;
        }
    
        public void setQueue(String queue) {
            this.queue = queue;
        }
    
        public boolean isDurable() {
            return isDurable;
        }
    
        public void setDurable(boolean durable) {
            isDurable = durable;
        }
    
        public int getConnectionTimeout() {
            return connectionTimeout;
        }
    
        public void setConnectionTimeout(int connectionTimeout) {
            this.connectionTimeout = connectionTimeout;
        }
    
        public void sendMessage(String msg){
    
            System.out.println("发送消息......");
        }
    
        /**
         * set方法的好处是参数的设计更加的灵活,但是通过set方式设置对象属性时,对象有可能存在中间状态(无效状态),
         * 并且进行属性校验时有前后顺序约束.
         * 破坏了不可变对象的密封性.
         * 怎么保证灵活设置参数又不会存在中间状态呢? 答案就是: 使用建造者模式
         */
        public static void main(String[] args) {
    
            RabbitMQClient2 client2 = new RabbitMQClient2();
            client2.setHost("192.168.52.123");
            client2.setMode(1);
            client2.setQueue("queue");
            client2.setDurable(true);
            client2.sendMessage("Test-MSG2");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134

    在这里插入图片描述
    4. Builder建造者类提供build()方法实现目标对象的创建

    /**
     * 建造者模式
     *      1.目标类的构造方法要传入一个Builder对象
     *      2.builder类位于目标类的内部,并且使用static修饰
     *      3.builder类对象提供内置各种set方法,注意: set方法的返回值是builder本身
     *      4.builder类提供一个build() 方法,实现目标对象的创建
     **/
    public class RabbitMQClient3 {
    
        //私有构造,目标类的构造方法要传入一个Builder对象
        private RabbitMQClient3(Builder builder){
    
        }
    
        //builder类位于目标类的内部,并且使用static修饰
        public static class Builder{
    
            //保证不可变对象的属性密闭性
            private String host = "127.0.0.1";
            private int port = 5672;
            private int mode;
            private String exchange;
            private String queue;
            private boolean isDurable = true;
            int connectionTimeout = 1000;
    
            //builder类对象提供内置各种set方法,注意: set方法的返回值是builder本身
            public Builder setHost(String host) {
                this.host = host;
                return this;
            }
    
            public Builder setPort(int port) {
                this.port = port;
                return this;
            }
    
            public Builder setMode(int mode) {
                this.mode = mode;
                return this;
            }
    
            public Builder setExchange(String exchange) {
                this.exchange = exchange;
                return this;
            }
    
            public Builder setQueue(String queue) {
                this.queue = queue;
                return this;
            }
    
            public Builder setDurable(boolean durable) {
                isDurable = durable;
                return this;
            }
    
            public Builder setConnectionTimeout(int connectionTimeout) {
                this.connectionTimeout = connectionTimeout;
                return this;
            }
    
            //builder类提供一个build() 方法,实现目标对象的创建
            public RabbitMQClient3 build(){
    
                if(mode == 1){ //工作队列模式不需要设计交换机,但是队列名称一定要有
                    if(exchange != null){
                        throw new RuntimeException("工作队列模式无需设计交换机");
                    }
                    if(queue == null || queue.trim().equals("")){
                        throw new RuntimeException("工作队列模式名称不能为空");
                    }
                    if(isDurable == false){
                        throw new RuntimeException("工作队列模式必须开启持久化");
                    }
                }else if(mode == 2){ //路由模式必须设计交换机,但是不能设计队列
                    if(exchange == null){
                        throw new RuntimeException("路由模式下必须设置交换机");
                    }
                    if(queue != null){
                        throw new RuntimeException("路由模式无须设计队列名称");
                    }
                }
    
                return new RabbitMQClient3(this);
            }
        }
    
        public void sendMessage(String msg){
    
            System.out.println("发送消息......");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    public class App {
    
        public static void main(String[] args) {
    
            //获取连接对象
            RabbitMQClient3 instance = new RabbitMQClient3.Builder().setHost("192.168.52.123").
                    setMode(1).setPort(5672).setQueue("test").build();
    
            instance.sendMessage("test");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    建造者模式总结

    在这里插入图片描述

    建造者模式的优缺点

    优点
    在这里插入图片描述
    在这里插入图片描述
    缺点
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    CART 算法——决策树
    python实现遗传算法,并绘制训练过程以及参数对比
    「GitLab篇」如何用Git平台账号登录建木CI
    常用的linux命令简要说明以及命令全名理解
    layui表格删除最后一页数据时,不会刷新到前一页问题:
    HTTP协议
    基于Bert+Attention+LSTM智能校园知识图谱问答推荐系统——NLP自然语言处理算法应用(含Python全部工程源码及训练模型)+数据集
    最受欢迎的编程语言排行榜
    排序 (爱思创算法四)(期中测试)(答案记录)
    在PHP8中使用instanceof操作符检测对象类型-PHP8知识详解
  • 原文地址:https://blog.csdn.net/weixin_39563769/article/details/133916637