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 {@Overridepublic void buildFrame() {System.out.println("制作车架!");mBike.setFrame("铝合金车架");}@Overridepublic void buildSeat() {System.out.println("制作车座");mBike.setSeat("真皮车座");}@Overridepublic Bike createBike() {return mBike;}
}
/*** 哈罗单车建造者 **/
public class HelloBikeBuilder extends Builder{@Overridepublic void buildFrame() {System.out.println("制作碳纤维车架");mBike.setFrame("碳纤维车架");}@Overridepublic void buildSeat() {System.out.println("制作橡胶车座");mBike.setFrame("橡胶车座");}@Overridepublic 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");}
}
建造者模式总结
建造者模式的优缺点
优点
缺点