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;
    }
}
/**
 * 抽象建造者类
 **/
public abstract class Builder {
	//申明一个protect对象给子类使用
    protected Bike mBike = new Bike();

    public abstract void buildFrame();

    public abstract void buildSeat();

    public abstract Bike createBike();
}
/**
 * 摩拜单车建造者
 **/
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;
    }
}
/**
 * 哈罗单车建造者	
 **/
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;
    }
}
指挥者类
/**
 * 指挥者类
 **/
public class Director {

    private Builder mBuilder;

    public Director(Builder mBuilder) {
        this.mBuilder = mBuilder;
    }


    //自行车制作方法
    public Bike construct(){
        mBuilder.buildFrame();
        mBuilder.buildSeat();
        return mBuilder.createBike();
    }
}
/**
 * 客户端
 **/
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());
    }

}
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");
    }
}

在这里插入图片描述

/**
 * 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");
    }
}

在这里插入图片描述
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("发送消息......");
    }

}
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");
    }
}

建造者模式总结

在这里插入图片描述

建造者模式的优缺点

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值