建造者模式的多层次理解

来源:互联网 发布:天融信网络管理系统 编辑:程序博客网 时间:2024/05/18 20:50
   

最近在学习设计模式,想要记录下来,今天就记录在android和Java中都使用得非常广泛的建造者模式(参照《Java与模式》一书)。

先看一下什么是建造模式:

  • 建造者模式(Builder):将一个产品的内部表象(Internal Representation)与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象。

建造者模式涉及的四个角色:

  • 抽象建造者(Builder)角色: 给出一个抽象接口,以规范产品对象的各个组成成分的构造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的两种方法:一种是建造方法;另一种是结果返还方法。一般来说,产品所包含的零件数目与建造方法的数目相符。换言之,有多少零件,就有多少相应的建造方法

  • 具体建造者(Concrete Builder)角色:担任这个角色的是与应用程序紧密相关的一些类,它们在应用程序调用下创建产品的实例。这个角色要完成的任务包括:实现抽象建造者Builder所声明的接口,给出一步一步地完成创建产品实例的操作;在建造过程完成后,提供产品的实例

  • 导演者角色(Director):担任这个角色的类调用具体建造者角色以创建产品对象。应当指出的是,导演者角色并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者角色

  • 产品(Product)角色:产品(Product)便是建造中的复杂对象。一般来说,一个系统中会有多于一个的产品类,而且这些产品类并不一定有共同的接口,而完全可以是不相关联的

了解了对应的组成角色之后,下面我们就以具体代码来理解建造者模式:
/**     * 产品类角色:这个类是与应用系统紧密相关的     * @author Administrator     *     */    public class Product    {    }    /**     * 抽象建造者角色:通常与应用系统的商业逻辑无关,会给出抽象接口,以规范产品对象的各个组成成分的构造    * @author Administrator    *    */    public abstract class Builder    {        /**         * 产品零件建造方法         */        public abstract void buildePart1();        /**         * 产品零件建造方法         */        public abstract void buildePart2();        /**         * 产品返还方法         * @return         */        public abstract Product retrieveResult();}    /**     * 具体建造者角色:与应用系统的商业逻辑紧密相关的,应当将产品实例化,并在各个建造方法中建造产品的各个零件,并通过方法retrieveResult()     * 返回最终产对象     *      * @author Administrator     *     */    public class ConcreteBuilder extends Builder    {        private Product product = new Product();        @Override        public void buildePart1()        {            System.out.println("建造第一部分");        }        @Override        public void buildePart2()        {            System.out.println("建造第二部分");        }        @Override        public Product retrieveResult()        {            return product;        }    }    /**     * 导演者角色:与客户端打交道的角色,导演者角色将客户端创建产品的请求划分为对各个零件的建造请求,再将这些请求     * 委派给具体建造者角色     * @author Administrator     *     */    public class Director    {        private Builder builder;        /**         * 产品构造方法,负责调用各个零件建造方法         */        public void construct()        {            builder = new ConcreteBuilder();            builder.buildePart1();            builder.buildePart2();        }    }    /**    *   客户端,测试    */          public class Client    {        public static void main(String[] args)        {            Director director = new Director();            Product product = director.construct();//此为我们最终要得到的产品        }    }    输出结果:    建造第一部分    建造第二部分
我觉得学习设计模式需要一定的时间跨度,我之所以把现在读到和想到的记录下来,是为了以后更好的翻阅。现在,来看一看它的变体,为的是更好的理解我们在日常Java和Android编程中所见的建造者模式。

省略导演者角色和抽象建造者角色

在具体建造者只有一个的情况下,如果抽象建造者角色已经被省略掉,那么还可以进一步省略掉导演着角色(看能不能画图),此时Builder角色自己就扮演了导演着和建造者的角色,有改变的类只有Builder类。此时的示意性代码就成了这样:
public class Builder {    private Product product = new Product();    /**     * 产品零件建造方法     */    public void buildPart1(){    }    /**     * 产品零件建造方法     */    public void buildPart2(){    }    public Product retrieveResult(){        return product;    }    /**     * 产品构造方法,负责调用各个零件建造方法     */    public void construct(){        buildPart1();        buildPart2();    }}public class Client{    public static void main(String[] args){        Builder builder = new Builder();        builder.construct();        Product product = builder.retrieveResult();    }}
public class Builder {    private Product product = new Product();    /**     * 产品零件建造方法     */    public void buildPart1(){    }    /**     * 产品零件建造方法     */    public void buildPart2(){    }    public Product retrieveResult(){        return product;    }    /**     * 产品构造方法,负责调用各个零件建造方法     */    public void construct(){        buildPart1();        buildPart2();    }}public class Client{    public static void main(String[] args){        Builder builder = new Builder();        builder.construct();        Product product = builder.retrieveResult();    }}

现在我们可以去理解Java中的StringBuilder和Android中的AlertDialog类了,先看StringBuilder:
StringBuilder sb = new StringBuilder();String str = sb.append("hello").append("world").append("welcome").toString();
这里面就是省略了导演者和抽象建造者角色的建造者模式,作为写这些代码的地方就是客户端,而StringBuilder就是那个具体建造者,最终的String就是产品角色。

再来看AlertDialog:

new AlertDialog.Builder(this).setTitle("数据删除").setMessage("你确定删除数据吗?")            .setPositiveButton("确定", new OnClickListener()            {                @Override                public void onClick(DialogInterface dialog, int which)                {                    Toast.makeText(DialogActivity.this, "删除成功",                            Toast.LENGTH_SHORT).show();                }            }).setNegativeButton("取消", new OnClickListener()            {                @Override                public void onClick(DialogInterface dialog, int which)                {                    Toast.makeText(DialogActivity.this, "取消删除",                            Toast.LENGTH_SHORT).show();                }            })            /*             * .setNeutralButton("Remind me later", new OnClickListener() {             *              * @Override public void onClick(DialogInterface dialog, int             * which) { Toast.makeText(DialogActivity.this, "以后再说",             * Toast.LENGTH_SHORT).show(); } })             */            .show();

这里,同样是省略了导演者和抽象建造者角色的建造者模式,编写这些代码的地方就是客户端,而AlertDialog就是产品,AlertDialog.Builder类就是具体建造者,它在show()中将产品返回(实际上类似于前面retrieveResult()方法个人认为是在show中调用的create(),不过对整体理解丝毫没有影响)。今天就记录到这里~(不足之处欢迎指出~)












0 0
原创粉丝点击