建造器基本模式Build Pattern

建造者模式 build pattern 也叫做生成器模式。将一个复杂对象分解,可以构建不同内置部分的对象

UML图:


建造者模式的核心是 builder,builder根据需求进行结构顺序的重新组成或者构造,然后一个builder返回一个对应符合需求的产品,这个与工厂模式的区别在于,工厂模式是整体进行制造,而builder主要是通过改变其内部组成。

director导演类用来封装builder,使其细节不暴露,这样的话,可以将builder的方法进行私有化。达到保护细节的作用。

这个模式感觉可以再进行演变,和其他模式结合在一起使用,以下是实例


1.使用静态内部类构造宠物

本类的亮点在于通过静态内部类的方式来对实体类进行建造。

隐藏了私有方法,可以根据需要来设置需要的参数。比如可以将必填项删除掉,有选择的进行参数的构造。

/**
 * 建造者模式
 */
public class Pet implements Serializable {

    private static final long serialVersionUID = -2582687321051957354L;

    /**
     * 静态内部类
     */
    public static class Builder implements Serializable {

        private static final long serialVersionUID = 3670075346133332769L;

        private Animal animal;
        private String petName;
        private String ownerName;
        private String address;
        private String telephone;
        private Date dateOfbirth;
        private String emailAddress;


        public Builder withEmailAddress(String emailAddress) {
            this.emailAddress = emailAddress;
            return this;
        }

        public Builder withAnimal(Animal animal) {
            this.animal = animal;
            return this;
        }

        public Builder withPetName(String petName) {
            this.petName = petName;
            return this;
        }

        public Builder withOwnerName(String ownerName) {
            this.ownerName = ownerName;
            return this;
        }

        public Builder withAddress(String address) {
            this.address = address;
            return this;
        }

        public Builder withTelephone(String telephone) {
            this.telephone = telephone;
            return this;
        }

        public Builder withDateOfbirth(Date dateOfbirth) {
            this.dateOfbirth = dateOfbirth;
            return this;
        }

        public Pet build() {
            if (null == address ||
                    null == petName ||
                    null == ownerName ||
                    null == dateOfbirth ||
                    null == emailAddress ||
                    null == telephone) {
                throw new IllegalStateException("Cannot create Pet");
            }
            return new Pet(animal, petName, ownerName, address, telephone, dateOfbirth, emailAddress);
        }
    }

    private Animal animal;
    private String petName;
    private String ownerName;
    private String address;
    private String telephone;
    private Date dateOfBirth;
    private String emailAdrress;

    private Pet(Animal animal, String petName, String ownerName, String address, String telephone, Date dateOfBirth, String emailAdrress) {
        this.animal = animal;
        this.petName = petName;
        this.ownerName = ownerName;
        this.address = address;
        this.telephone = telephone;
        this.dateOfBirth = dateOfBirth;
        this.emailAdrress = emailAdrress;
    }

    /**
     * 测试方法
     * @param args
     */
    public static void main(String[] args) {
        // 声明构造器
        Pet.Builder build = new Pet.Builder();
        // 构造对象
        Pet pet = build.withAnimal(Animal.DOG)
                .withPetName("lily")
                .withOwnerName("smith")
                .withTelephone("132345555")
                .withAddress("123 high street")
                .withDateOfbirth(new Date())
                .withEmailAddress("1234@qq.com")
                .build();
        System.out.println(pet);
    }
}

2.  不同宝马车和奔驰车的建造,

以下示例对车类的行为进行抽象,共同的部分和不同的本分分别实现

建造者实际上也可以使用一个实现类,但是如果需要更多的细节,可以封装在建造者当中,以下示例中将车的次序封装在到导演类中实际上不太好,应该将这部分封装在不同的builder当中,然后导演类直接调用更为妥当,导演类中展示了太多细节部分。

宝马的共性:启动、停止、鸣笛、引擎响,跑

以上的顺序四辆跑车各不相同,顺序由客户来决定,决定的 顺序使用List<String> 集合来组装,然后遍历出来执行

A宝马:只有启动、停止,没有鸣笛和引擎响

B宝马:先引擎响,然后启动、停止,没鸣笛

A奔驰:先鸣笛、再的启动,然后停车

B奔驰:先启动,然后一路跑,不需要停止、鸣笛、引擎、一直跑

抽象类车:

public abstract class AbstractCarModel {

    private List<String> seq;

    protected abstract void start();
    protected abstract void stop();
    protected abstract void alarm();
    protected abstract void engineBoom();

    /**
     * 遍历执行顺序
     */
    protected void run(){
        for (String step : seq) {
            if ("start".equals(step.toLowerCase())) {
                this.start();
            }
            if ("stop".equals(step.toLowerCase())) {
                this.stop();
            }
            if ("alarm".equals(step.toLowerCase())) {
                this.alarm();
            }
            if ("engineBoom".equals(step.toLowerCase())) {
                this.engineBoom();
            }
        }
    }

    /**
     *  设置执行顺序
     * @param seq
     */
    protected void setSeq(List<String> seq){
        this.seq = seq;
    }
}

宝马车及奔驰车实现类

public class BMWModel extends AbstractCarModel {

    public void start() {
        System.out.println("宝马启动");
    }

    public void stop() {
        System.out.println("宝马停车");
    }

    public void alarm() {
        System.out.println("宝马鸣笛");
    }

    public void engineBoom() {
        System.out.println("宝马引擎响");
    }
}
public class BENZModel extends AbstractCarModel {

    public void start() {
        System.out.println("奔驰启动");
    }

    public void stop() {
        System.out.println("奔驰停车");
    }

    public void alarm() {
        System.out.println("奔驰鸣笛");
    }

    public void engineBoom() {
        System.out.println("奔驰引擎响");
    }
}

抽象类建造类:

public abstract class AbstractCarBuilder {

    protected abstract AbstractCarModel getCarModel();
    protected abstract void setSeq(List<String> seq);

}

宝马车及奔驰车建造实现类

public class BMWBuilder extends AbstractCarBuilder {

    private AbstractCarModel bmw = new BMWModel();

    @Override
    public AbstractCarModel getCarModel() {
        return bmw;
    }

    @Override
    public void setSeq(List<String> seq) {
        bmw.setSeq(seq);
    }
}
public class BENZBuilder extends AbstractCarBuilder {

    private AbstractCarModel benz = new BENZModel();

    @Override
    protected AbstractCarModel getCarModel() {
        return benz;
    }

    @Override
    protected void setSeq(List<String> seq) {
        benz.setSeq(seq);
    }
}

3.  建造者模式可以用作不同的数据处理handler,比如同步表中记录了需要不同handler进行处理的数据记录,此时的handler也类似于建造者中的一个个builder分别处理针对数据进行不同的处理,这样开发者编写不同的handler进行数据处理,而查询出来的数据根据handler的不一样进行处理,以下尝试做一个模式演示:

job的调用采用web方式进行(controller)调用


以下主要模拟相应的handler进行实现。使用一个map容器来装载相应的TransHandler实例,这个有点像容器模式了。

(1) 定义接口

public interface TransHandler {
    void execute(JobEntity param);
}

(2) 一个抽象类继承它,并且编写实例注册方法

public abstract class AbstractTransHandler implements TransHandler {

    @PostConstruct
    public void registerHandler(){
        String handlerName = this.getClass().getSimpleName();
        // 截取开头及到transhandler部分作为key进行存储
        handlerName = handlerName.substring(0, handlerName.lastIndexOf("TransHandler"));
        TransHandlerManager.register(handlerName.toLowerCase(),this);
    }
}

(3) 编写处理实例,并且让实例随着spring容器启动实例化

/**
 *  随spring容器启动的时候,执行PostStruct标记的方法即完成了相应的TransHandler注册
 */
@Service
public class SpiderTransHandler extends AbstractTransHandler{

    @Override
    public void execute(JobEntity param) {
        System.out.println("dosomething with param");
    }
}

(4) 上述引用的容器类工具

public class TransHandlerManager {

    private static Map<String, Object> handlers = new ConcurrentHashMap<>(100);

    private TransHandlerManager() {
    }

    public static void register(String key, TransHandler handler){
        if (null!= handler && null== handlers.get(key)&& null != key){
            handlers.put(key, handler);
        }
    }

    public static TransHandler getHandler(String key){
        return (TransHandler) handlers.get(key);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值