设计模式之建造者模式

2018-05-23  本文已影响0人  runningboys
定义:

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

使用场景:
(1)相同的使用方法,不同的执行顺序,产生不同的事件结果时。
(2)多个部件或零件,都可以装配到一个对象中,但是产生的运行结果又不相同时。
(3)产品类非常复杂,或者产品类中的调用顺序不同产生了不同的作用。
(4)当初始化一个对象特别复杂,如参数多,且很多参数都具有默认值时。

/**
 * 抽象产品类
 */
abstract class Product {
    protected String name;
    protected String type;

    public void setName(String name) {
        this.name = name;
    }

    public void setType(String type) {
        this.type = type;
    }

    public abstract void showProduct();
}

/**
 * 小米手机
 */
public class XiaoMiPhone extends Product {
    
    @Override
    public void showProduct() {
        System.out.println("名称:" + name + "型号:" + type);
    }
}

/**
 * 抽象建造者类
 */
abstract class Builder {
    public abstract Builder setName(String name);

    public abstract Builder setType(String type);

    public abstract Product create();
}

/**
 * 具体建造者
 */
class ConcreteBuilder extends Builder {
    private Product product = new XiaoMiPhone();

    @Override
    public Builder setName(String name) {
        product.setName(name);
        return this;
    }

    @Override
    public Builder setType(String type) {
        product.setType(type);
        return this;
    }

    @Override
    public Product create() {
        return product;
    }

    /**
     * 动态注入不同产品
     *
     * @param product
     */
    public void setProduct(Product product) {
        this.product = product;
    }
}

/**
 * 指挥者--用于具体产品的构造
 */
public class Director {
    private Builder builder;

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

    public Product constructA(String name, String type) {
        return builder.setName(name).setType(type).create();
    }

    public Product constructB(String name, String type) {
        return builder.setType(type).setName(name).create();
    }
}

/**
 * 客户端调用
 */
public class Client {
    public static void main(String[] args) {
        Builder builder = new ConcreteBuilder();
        Director director = new Director(builder);
        Product productA = director.constructA("小米", "MI-6X");
        productA.showProduct();
        Product productB = director.constructB("为发烧而生:小米", "MI-6X");
        productB.showProduct();
    }
}

安卓源码中的常见用法:

AlertDialog.Builer builder=new AlertDialog.Builder(context);
builder.setIcon(R.drawable.icon)
    .setTitle("title")
    .setMessage("message")
    .setPositiveButton("Button1", 
        new DialogInterface.OnclickListener(){
            public void onClick(DialogInterface dialog,int whichButton){
                setTitle("click");
            }   
        })
    .create()
    .show();

最简单常用的写法:

/**
 * 苹果手机
 */
public class ApplePhone {
    private String name;
    private String type;

    public static class Builder {
        private String name;
        private String type;

        public Builder setName(String name){
            this.name = name;
            return this;
        }

        public Builder setType(String type){
            this.type = type;
            return this;
        }

        public ApplePhone create() {
            ApplePhone phone = new ApplePhone();
            phone.name = name;
            phone.type = type;
            return phone;
        }
    }
}

/**
 * 客户端调用
 */
public class Client {
    public static void main(String[] args) {
        ApplePhone.Builder builder = new ApplePhone.Builder();
        ApplePhone phone = builder.setType("Iphone8X").setName("我是一个小苹果").create();
    }
}

建造者模式的优点是封装性好,且易于扩展。建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给指挥者类。由指挥者类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。

上一篇下一篇

猜你喜欢

热点阅读