创建者模式

来源:互联网 发布:新浪微博怎么去丢域名 编辑:程序博客网 时间:2024/05/07 22:39

  各个品牌的汽车在工厂生好了,现在需要对这些汽车进行试驾,每个品牌的汽车试驾流程不一样,奥迪汽车试驾流程是先启动,再鸣笛,再行驶,最后停车;奔驰试驾流程是先鸣笛,再启动,然后行驶,最后停车;保时捷的试驾流程也不一样,需求可以多变,面对这种情况我们应该怎么实现呢?
来看实现代码吧:

抽象汽车类(CarModel)

public abstract  class CarModel{    private ArrayList<String> list = new ArrayList<String>();    protected abstract void start();    protected abstract void stop();    protected abstract void alarm();    final public void run(){        for(String str : list)        {            switch (str) {            case "start": this.start();break;            case "stop": this.stop();break;            case "alarm": this.alarm();break;            default:                break;            }        }    }    final public void setList(ArrayList<String> list)    {        this.list =  list;    }}

具体的车型(AudiCarModel)

public class AudiCarModel extends CarModel{    @Override    protected void start()    {        // TODO Auto-generated method stub        System.out.println("奥迪车启动");    }    @Override    protected void stop()    {        // TODO Auto-generated method stub        System.out.println("奥迪车停止");    }    @Override    protected void alarm()    {        // TODO Auto-generated method stub        System.out.println("奥迪车鸣笛");    }}

具体的车型(BenzCarModel )

public class BenzCarModel extends CarModel{    @Override    protected void start()    {        // TODO Auto-generated method stub        System.out.println("奔驰车启动");    }    @Override    protected void stop()    {        // TODO Auto-generated method stub        System.out.println("奔驰车停止");    }    @Override    protected void alarm()    {        // TODO Auto-generated method stub        System.out.println("奔驰车鸣笛");    }}

试驾场景类(Client)通过把试驾顺序流程封装到List中:

public class Client{        public static void main(String[] args)        {            BenzCarModel benz = new BenzCarModel();            ArrayList<String> benzList = new ArrayList<String>();            benzList.add("start");            benzList.add("alarm");            benzList.add("stop");            benz.setList(benzList);            benz.run();            AudiCarModel audi = new AudiCarModel();            ArrayList<String> audiList = new ArrayList<String>();            audiList.add("start");            audiList.add("stop");            audiList.add("alarm");            audi.setList(audiList);            audi.run();        }}

试驾结果:

奔驰车启动奔驰车鸣笛奔驰车停止奥迪车启动奥迪车停止奥迪车鸣笛

  需求总算完成了,我们可以在Client类中增加不同车的试驾流程,但是需求流程千变万化,我们不可能一个一个的来写场景类来满足需求,我们可以为每种车型定义一个建造者,你要啥试驾流程直接告诉建造者,由它完成建造,于是需要添加一个CarBuilder抽象类,由它来构建试驾流程,要什么试驾流程由它的相关子类完成。
  
汽车试驾流程创建者(CarBuilder)

public abstract class CarBuilder{        public abstract void setList(ArrayList<String> list);        public abstract CarModel getCarModel();}

奥迪试驾流程组装者(AudiBuilder ):

public class AudiBuilder extends CarBuilder{    private AudiCarModel audi = new AudiCarModel();    @Override    public void setList(ArrayList<String> list)    {        // TODO Auto-generated method stub        this.audi.setList(list);    }    @Override    public CarModel getCarModel()    {        // TODO Auto-generated method stub        return audi;    }}

奔驰试驾流程组装者(AudiBuilder ):

public class BenzBuilder extends CarBuilder{    private BenzCarModel benz = new BenzCarModel();    @Override    public void setList(ArrayList<String> list)    {        // TODO Auto-generated method stub        this.benz.setList(list);    }    @Override    public CarModel getCarModel()    {        // TODO Auto-generated method stub        return benz;    }}

修改后的试驾场景类:

public class Client2{    public static void main(String[] args)    {        ArrayList<String> benzList = new ArrayList<String>();        benzList.add("start");        benzList.add("alarm");        benzList.add("stop");        BenzBuilder benzBuilder = new BenzBuilder();        benzBuilder.setList(benzList);        BenzCarModel benz = (BenzCarModel) benzBuilder.getCarModel();        benz.run();        ArrayList<String> audiList = new ArrayList<String>();        audiList.add("start");        audiList.add("stop");        audiList.add("alarm");        AudiBuilder audiBuilder = new AudiBuilder();        audiBuilder.setList(benzList);        AudiCarModel audi = (AudiCarModel) audiBuilder.getCarModel();        audi.run();    }}

试驾流程结果与上述实现结果一样

奔驰车启动奔驰车鸣笛奔驰车停止奥迪车启动奥迪车停止奥迪车鸣笛

  试驾流程可以千变万化,我们不可以能预知需要什么样的试驾流程,因此我们需要封装一下,找一个导演来指挥各个试驾流程为每种流程制定一个代码,需要什么流程,我马上就能执行,下面来看一下修改后的代码。
  
导演类(Director):

public class Director{     private ArrayList<String> list = new ArrayList();     public BenzBuilder benzBuilder = new  BenzBuilder();     private AudiBuilder audiBuilder = new AudiBuilder();     public BenzCarModel getBenzACarModel()     {         this.list.clear();         list.add("start");         list.add("alarm");         list.add("stop");         this.benzBuilder.setList(list);         return (BenzCarModel) this.benzBuilder.getCarModel();     }     public BenzCarModel getBenzBCarModel()     {         this.list.clear();         list.add("start");         list.add("stop");         list.add("alarm");         this.benzBuilder.setList(list);         return (BenzCarModel) this.benzBuilder.getCarModel();     }     public AudiCarModel getAudiA6CarModel()     {         this.list.clear();         list.add("start");         list.add("stop");         list.add("alarm");         this.audiBuilder.setList(list);         return (AudiCarModel) this.audiBuilder.getCarModel();     }     public AudiCarModel getAudiA8CarModel()     {         this.list.clear();         list.add("start");         list.add("stop");         list.add("alarm");         this.audiBuilder.setList(list);         return (AudiCarModel) this.audiBuilder.getCarModel();     }}

试驾流程类:

public class Client1{    public static void main(String[] args)    {        Director d = new Director();        for(int i =0;i<5;i++)        {            d.getBenzACarModel().run();        }        for(int i =0;i<5;i++)        {            d.getBenzBCarModel().run();        }        for(int i =0;i<5;i++)        {            d.getAudiA6CarModel().run();        }        for(int i =0;i<5;i++)        {            d.getAudiA8CarModel().run();        }    }}

试驾结果:

奔驰车启动奔驰车鸣笛奔驰车停止奔驰车启动奔驰车鸣笛奔驰车停止奔驰车启动奔驰车鸣笛奔驰车停止奔驰车启动奔驰车鸣笛奔驰车停止奔驰车启动奔驰车鸣笛奔驰车停止奔驰车启动奔驰车停止奔驰车鸣笛奔驰车启动奔驰车停止奔驰车鸣笛奔驰车启动奔驰车停止奔驰车鸣笛奔驰车启动奔驰车停止奔驰车鸣笛奔驰车启动奔驰车停止奔驰车鸣笛奥迪车启动奥迪车停止奥迪车鸣笛奥迪车启动奥迪车停止奥迪车鸣笛奥迪车启动奥迪车停止奥迪车鸣笛奥迪车启动奥迪车停止奥迪车鸣笛奥迪车启动奥迪车停止奥迪车鸣笛奥迪车启动奥迪车停止奥迪车鸣笛奥迪车启动奥迪车停止奥迪车鸣笛奥迪车启动奥迪车停止奥迪车鸣笛奥迪车启动

  有了导演类,我们的场景类就好处理各种需求了,这就是建造者模式。
  
建造者模式定义:Separate the construction of a complex object form its representation so that the same construction process can create different representations.(将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。)

建造者模式主要有4个角色:
  产品类:通常实现了模板方法模式,比如我们示例代码中的AudiCarModel和BenzCarModel类。
  抽象构建者:规范产品的组建,一般有子类实现,比如上述事例代码中的CarBuilder类。
  具体构建者:实现抽象构建者的所有方法,并且返回一个组建好的对象,不如BenzBuilder和AudiBuilder类。
  导演类 :负责安排已有模块的顺序然后告诉建造者开始建造,比如Director类。
建造者模式优点:
  封装性:可以使客户端不必知道产品内部组成的细节。
  建造者独立,容易扩展:BenzBuilder与AudiBuilder是相对独立,对系统扩展非常有利。
  便于控制细节风险

0 0
原创粉丝点击