建造者模式 又称为生成器模式(设计模式之禅 101-112页)
定义:
将一个复杂对象的构建与它的表示分开,使得同样的创建过程可以创建不同的表示
在建造者模式中,有如4个角色
Product 产品类
通常是实现了模板方法模式,也就是有模板方法和基本方法
Builder抽象创建者
规范产品的创建,一般由子类实现。
ConcreteBuilder具体创建者
实现抽象类定义的所有方法,并返回一个组建好的对象
Director导演类
负责安排已有的模块顺序,然后告诉Builder开始创建。
产品类
public class Product {
public void doSomething(){
//独立的业务处理
}
}
抽象建造者
public abstract class Builder{
//设计产品的不同部分,以获取不同的产品
public abstract void setPart();
//创建产品
public abstract Product builProduct();
}
具体创建者
public class ConcreteProduct extends Builder {
Private Product product = new Product();
//设置产品零件
public void setPart(){
/*
* 产品类内的逻辑处理
*/
//组建一个产品
public Product buildProduct() {
return product;
}
}
注意:有多少个产品类就有多少个具体的创建者,而且这多个产品类具有相同接口或抽象类
导演类:
public class Director {
private Builder builder = new ConcreteProduct();
//构建不同的产品
public Product getAProduct(){
builder.setPart();
/*
* 设置不同的零件,产生不同的产品
*/
return builder.buildProduct();
}
}
优点:
封装性
使用建造者模式可以使客户端不必知道产品内部组成的细节,如例子中我们就不需要关心每一个具体的模型内部是如何实现的,产生的对象类型就是Product。
建造者独立,容易扩展
每个建造者相互独立,对系统的扩展非常有利
便于控制细节风险
由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何的影响
使用场景
相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式
多个部件或者零件,都可以装配到一个对象中,但是产生的结果又不相同时
产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能
建造者模式和工厂方法非常相似,但是建造者模式最主要的功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了,通俗来说就是零件的装配,顺序不同产生的对象也不同;而工厂方法则重点是创建,创建零件是它的主要职责,组装顺序则不是它关心的。
示例代码:
//抽象产品类
public abstract class AbstractProduct {
ArrayList<String> list = new ArrayList();
protected abstract void open();
protected abstract void close();
protected abstract void music();
public final void run (){
int size = this.list.size();
for (int i=0; i<size;i++ ){
String actionName = this.list.get(i);
if (actionName.equalsIgnoreCase("open")){
this.open();
}else if (actionName.equalsIgnoreCase("close")){
this.close();
}else if (actionName.equalsIgnoreCase("music")){
this.music();
}
}
}
public final void setList(ArrayList<String> list){
this.list = list;
}
}
//产品类
public class Product extends AbstractProduct{
@Override
public void open(){
System.out.println("打开手机");
}
@Override
public void close(){
System.out.println("关闭手机");
}
@Override
public void music(){
System.out.println("听音乐");
}
}
//抽象建造者
public abstract class Builder {
//设计产品的不同部分,以获取不同的产品
public abstract void setPart(ArrayList<String> list);
//创建产品
public abstract AbstractProduct builProduct();
}
//具体建造者
public class ConcreteProduct extends Builder{
private AbstractProduct product = new Product();
@Override
public void setPart(ArrayList<String> list) {
this.product.setList(list);
}
@Override
public AbstractProduct builProduct() {
return this.product;
}
}
//导演类
public class Director {
private ArrayList<String> list = new ArrayList<>();
private Builder builder = new ConcreteProduct();
//只开机和关机
public AbstractProduct getMethod1(){
this.list.clear();
list.add("open");
list.add("close");
builder.setPart(list);
return builder.builProduct();
}
//只开机和听音乐
public AbstractProduct getMethod2(){
this.list.clear();
list.add("open");
list.add("music");
builder.setPart(list);
return builder.builProduct();
}
//开机,关机,听音乐
public AbstractProduct getMethod3(){
this.list.clear();
list.add("open");
list.add("close");
list.add("music");
builder.setPart(list);
return builder.builProduct();
}
}
public class main {
public static void main(String[] args) {
Director director = new Director();
director.getMethod1().run();
System.out.println("----------------");
director.getMethod2().run();
System.out.println("----------------");
director.getMethod3().run();
}
}
由于demo代码比较多 如果需要的话 可以去下载我写的demo
demo: https://gitee.com/minstrel01/Design-Pattern-demo.git builder_pattern