zoukankan      html  css  js  c++  java
  • 23种设计模式之--建造者模式

    又是一个周三,快要下班了,老大突然拉住我,喜滋滋的告诉我:“XX公司很满意我们做的模型,又签订了一个合同,把奔驰、宝马的车辆模型都交给我们公司制作了,不过这次又额外增加了一个需求:汽车的启动、停止、喇叭声音、引擎声音都由客户自己控制,他想什么顺序就什么顺序, 这个没问题吧?”

    又是一个时间紧,工程量大的项目。首先,我们分析一下需求,奔驰、宝马都是一个产品,它们有共有的属性,XX公司关心的是单个模型的运行过程:奔驰模型A先有引擎声音,然后再响喇叭;奔驰B是先启动起来,然后再有引擎声音,这才是XX公司要关心的。那到我们老大这边呢,就是满足人家的要求,要什么顺序就立马能产生什么顺序的模型出来,我就负责老大的要求实现出来,而且还要批量的,也就是说XX公司下单订购宝马A车模,我们老大马上就找我“生产一个这样的车模, 启动完毕后,喇叭响一下”,然后我们就准备开始批量生产这些模型。

    看起来需求还是比较复杂,我们一个个解决,先从产品类入手。

    public abstract class CarModel
    {
        private List<String> sequence = new ArrayList<String>();
    
        final public void setSequence( List<String> sequence )
        {
            this.sequence = sequence;
        }
    
        protected abstract void start();
    
        protected abstract void stop();
    
        protected abstract void alarm();
    
        protected abstract void engineBoom();
    
        final public void run()
        {
            for ( String actionName : sequence )
            {
                if ( actionName.equalsIgnoreCase( "start" ) )
                {
                    this.start();
                } else if ( actionName.equalsIgnoreCase( "stop" ) )
                {
                    this.stop();
                } else if ( actionName.equalsIgnoreCase( "alarm" ) )
                {
                    this.alarm();
                } else if ( actionName.equalsIgnoreCase( "engine boom" ) )
                {
                    this.engineBoom();
                }
            }
        }
    }

    CarModel的设计原理是这样的,setSequence方法是允许客户自己设置一个顺序,是要先启动响一下喇叭再跑起来,还是要先响一下喇叭再启动。对于一个具体的模型永远都固定的,但是对于N多个模型就是动态的了。在子类中实现父类的基本方法,run方法读取sequence, 然后遍历sequence中的字符吕,哪个字符串在先,就先执行哪个方法。

    奔驰模型代码:

    public class BenzModel extends CarModel
    {
        @Override
        protected void alarm()
        {
            System.out.println( "Benz alarmming" );
        }
    
        @Override
        protected void engineBoom()
        {
            System.out.println( "Benz startup engine boom" );
        }
    
        @Override
        protected void start()
        {
            System.out.println( "Benz startting" );
        }
    
        @Override
        protected void stop()
        {
            System.out.println( "Benz Stopping" );
        }
    }

    宝马模型代码:

    public class BWMModel extends CarModel
    {
        @Override
        protected void alarm()
        {
            System.out.println( "BWM alarmming" );
        }
    
        @Override
        protected void engineBoom()
        {
            System.out.println( "BWM startup engine boom" );
        }
    
        @Override
        protected void start()
        {
            System.out.println( "BWM startting" );
        }
    
        @Override
        protected void stop()
        {
            System.out.println( "BWM Stopping" );
        }
    }

    两个产品类实现都完成,我们来模拟一下XX公司的要求:生产一个奔驰模型,要求跑的时候,先发动引擎,然后再挂挡启动,然后停下来,不需要喇叭。

    public class Client
    {
        public static void main( String[] args )
        {
            CarModel benz = new BenzModel();
            List<String> sequence = new ArrayList<String>();
            sequence.add( "engine boom" );
            sequence.add( "start" );
            sequence.add( "stop" );
            benz.setSequence( sequence );
            benz.run();
        }
    }

    看, 我们组装了这样的一辆汽车,满足了XX公司的需求。但是想想我们的需求, 汽车动作顺序是要能够随意调整的。所有我们应该为产品模型定义一个建造者,你要啥顺序直接告诉建造者,由建造者建造。

    这样才以批量生产某种类型的汽车。

    public abstract class CarBuilder
    {
        public abstract void setSequence( List<String> sequence);
        public abstract CarModel getCarModel();
    }
    public class BenzBuilder extends CarBuilder
    {
        private CarModel benz = new BenzModel();
    
        @Override
        public CarModel getCarModel()
        {
            return this.benz;
        }
    
        @Override
        public void setSequence( List<String> sequence )
        {
            this.benz.setSequence( sequence );
        }
    }
    public class BWMBuilder extends CarBuilder
    {
        private CarModel bwm = new BWMModel();
    
        @Override
        public CarModel getCarModel()
        {
            return this.bwm;
        }
    
        @Override
        public void setSequence( List<String> sequence )
        {
            this.bwm.setSequence( sequence );
        }
    }

    现在我们生产同一种类型的汽车就容易多了

    public class Client
    {
        public static void main( String[] args )
        {
            List<String> sequence = new ArrayList<String>();
            sequence.add( "engine boom" );
            sequence.add( "start" );
            sequence.add( "stop" );
    
            BenzBuilder benzBuilder = new BenzBuilder();
            benzBuilder.setSequence( sequence );
    
            CarModel benz = benzBuilder.getCarModel();
            benz.run();
        }
    }

    我们做项目时,经常会有一个共识:需求是无底洞,是无理性的,不可能你告诉它不增加需求就不增加,这4个过程(start,stop,alarm,engineBoom)按照排列组合有很多种,XX公司可以随意组合,它要什么顺序的车模我就必须生成什么顺序的车辆,客户就是上帝,所有我们应该找一个导演,指挥各个事件的先后顺序,然后为每种顺序指定一个代码,你说一种我们立刻给你生产处理。

     

  • 相关阅读:
    运输计划[二分答案 LCA 树上差分]
    树的重心与树的直径
    约瑟夫问题
    [The 2019 Asia Yinchuan First Round Online Programming] D Take Your Seat
    CF858F Wizard's Tour
    当那一天来临
    NOI2000 青蛙过河[递推]
    BZOJ4305 数列的GCD
    中国剩余定理和扩展中国剩余定理
    重写select
  • 原文地址:https://www.cnblogs.com/zfc2201/p/3461852.html
Copyright © 2011-2022 走看看