• 建造者模式



    建造者模式


    • 建造者模式也叫作生成器模式,将一个复杂对象的创建与它的表示分离,使得同样的构建过程可以创建不同的表示(Separate the construction of a complex object from its representation so that the same construction process can create different representations)。

    • 建造者模式中有4个角色,其通用类图如下:

      • Product产品类通常是实现了模板方法模式,也就是有模板方法和基本方法。通常以抽象类和具体类(类图中省略了抽象类)。参考详细例子中的BenzModel和BMWModel类。

      • Builder抽象建造者规范产品的组建,定义抽象方法,一般由具体的构建子类实现。详细例子中的CarBuilder就属于抽象建造者。
      • ConcreteBuilder具体建造者实现抽象类定义的所有方法,并且返回一个组建好的对象。参见详细例子中的BenBuilder和BMWBuilder。
      • Director导演类负责安排已有模板的顺序,然后传递给Builder开始建造。
      • 建造者的通用源码如下
      • public class Product {
            private void doSomething(){
                //产品的业务处理
            }
        }
        
        public abstract class Builder {
            //设置产品的不同部分,以获得不同的产品
            public abstract void setPart();
            //建造产品
            public abstract Product buildProduct();
        }
        
        public class ConcreteBuilder extends Builder{
            private Product product = new Product();
            @Override
            public void setPart() {
                // TODO Auto-generated method stub
                //产品类内部的逻辑处理
            }
        
            @Override
            public Product buildProduct() {
                // TODO Auto-generated method stub
                return product;
            }
        }
        
        public class Director {
            private Builder builder = new ConcreteBuilder();
            public Product getProduct(){
                builder.setPart();
                return builder.buildProduct();
            }
        }
      • 详细例子的通用类图和源码如下

    public abstract class CarModel {
        private ArrayList<String> sequence = new ArrayList<String>();
        protected abstract void start();
        protected abstract void alarm();
        protected abstract void stop();
        final public void run(){
            for(int i = 0; i < sequence.size(); i++){
                String actionName = sequence.get(i);
                if(actionName.equalsIgnoreCase("start")){
                    this.start();
                }else if(actionName.equalsIgnoreCase("stop")){
                    this.stop();
                }else if(actionName.equalsIgnoreCase("alarm")){
                    this.alarm();
                }
            }
        }
        final public void setSequence(ArrayList<String> sequence){
            this.sequence = sequence;
        }
    }
    
    public class BenzModel extends CarModel{
        @Override
        protected void start() {
            // TODO Auto-generated method stub
            System.out.println("奔驰车启动");
        }
        @Override
        protected void alarm() {
            // TODO Auto-generated method stub
            System.out.println("奔驰车鸣笛");
        }
        @Override
        protected void stop() {
            // TODO Auto-generated method stub
            System.out.println("奔驰车停止");
        }
    }
    
    public class BMWModel extends CarModel{
        @Override
        protected void start() {
            // TODO Auto-generated method stub
            System.out.println("宝马车启动");
        }
        @Override
        protected void alarm() {
            // TODO Auto-generated method stub
            System.out.println("宝马车鸣笛");
        }
        @Override
        protected void stop() {
            // TODO Auto-generated method stub
            System.out.println("宝马车停止");
        }
    }
    
    public abstract class CarBuilder {
        protected abstract void setSequence(ArrayList<String> sequence);
        protected abstract CarModel getCarModel();
    }
    
    public class BenzBuilder extends CarBuilder{
        private BenzModel benz = new BenzModel();
        @Override
        protected void setSequence(ArrayList<String> sequence) {
            // TODO Auto-generated method stub
            benz.setSequence(sequence);
        }
        @Override
        protected CarModel getCarModel() {
            // TODO Auto-generated method stub
            return this.benz;
        }
    }
    
    public class BMWBuilder extends CarBuilder{
        private BMWModel bmw = new BMWModel();
        @Override
        protected void setSequence(ArrayList<String> sequence) {
            // TODO Auto-generated method stub
            bmw.setSequence(sequence);
        }
    
        @Override
        protected CarModel getCarModel() {
            // TODO Auto-generated method stub
            return this.bmw;
        }
    }
    
    public class Director {
        private ArrayList<String> sequence = new ArrayList<String>();
        private BenzBuilder benz = new BenzBuilder();
        private BMWBuilder bmw = new BMWBuilder();
        public BenzModel getBenzModel(){
            this.sequence.clear();
            this.sequence.add("start");
            this.sequence.add("stop");
            benz.setSequence(sequence);
            return (BenzModel)benz.getCarModel();
        }
        public BMWModel getBMWModel(){
            this.sequence.clear();
            this.sequence.add("start");
            this.sequence.add("alarm");
            this.sequence.add("stop");
            this.bmw.setSequence(sequence);
            return (BMWModel)this.bmw.getCarModel();
        }
    }
    
    public class Client {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Director director = new Director();
            director.getBenzModel().run();
            director.getBMWModel().run();
        }
    }
    View Code
    • 建造者模式的优点

      • 封装性使用建造者模式可以使客户端不必知道产品内部组成的细节,如例子中我们不必关系每一个具体的模型内部是如何实现的,产生的对象类型就是CarModel。
      • 建造者独立,容易扩展BenzBuilder和BMWBuilder相互独立,有利于系统扩展。
      • 便于控制细节风险由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
    • 建造者模式的使用场景

      • 相同的方法,不同的执行顺序,产生不同的事件结果,可以采用建造者模式;
      • 多个部件或零件都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式;
      • 产品类非常复杂,或者产品类中的顺序不同产生不同的效能,则可以使用建造者模式;
      • 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。该种场景只能是一个补偿方法,因为一个对象不容易获得,而在设计阶段竟然没有发觉,而要通过创建者模式柔化创建过程,本身就违反了设计的最初目标。
    • 最佳实践

    本文中列举的实例,通过将建造者模式和模板方法模式进行结合,就是一个对建造者模式很好的扩展实践。

  • 相关阅读:
    使用Fiddler捕获Java程序中的HTTP请求
    js解析json对象和json字符串
    写代码 在与思考
    sql 逻辑读取次数
    WbeAPI 学习笔记
    大话设计模式阅读笔记
    行转列
    sql server 的多表查询(left join )
    union 和union all比较
    sql 跨库和域插入数据库
  • 原文地址:https://www.cnblogs.com/zhanglei93/p/6038121.html
Copyright © 2020-2023  润新知