Java创建型设计模式-建造者(3)

来源:互联网 发布:java swing的网格布局 编辑:程序博客网 时间:2024/06/05 04:28

#建造者模式

定义

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

参与者

这里写图片描述

Product(产品):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义的它的装配过程。

Builder(接口):为创建一个Product对象的各个部件指定抽象的接口。

ConcreteBuilder(实现接口):实现Builder接口实现构造和装配产品的各个部件。

Director(使用构造对象):构造一个使用Builder接口的对象。

总结:Product是主要是应有产品的属性和行为。Builder负责构造出抽象接口,主要是构造部件的方法和获得产品类(&部件)的方法,ConcreteBuilder负责实现Builder接口,Director引用ConcreteBuilder进行构造产品。

适用性

1.当创建十分复杂对象应该独立于对象组成部分以及它们的装配方式时。例对话框,有许多不同的部件标题、内容、按钮和View。

2.当构造过程必须允许被构造对象有不同的表示时。例对话框,有些需要显示标题、内容、不同的按钮、不同View等,但有些却不需要,我们就对所需要的进行装配。

实现

例如我们要构造一个对话框。

Product(产品):拥有标题(title)和信息(message)的属性,显示行为-方法:show()。

Builder(接口):创造建立部件的方法setTitle()&setMessage(),获得产品的方法。

ConcreteBuilder(实现接口):实现Builder接口,得到产品类的实例,把产品的部件和构造连接起来,使得建立部件的方法得以实现。

Director(使用构造对象):构造一个使用Builder接口的对象。

废话不多说,上代码。

Product

package example;/** * @author Created by MadJieJie on 2017/4/17-14:00. * @brief * @attention */public class Product{    public String title;    public String message;    public void show ()    {        System.out.println("title:" + title);        System.out.println("message:" + message);    }    public void setTitle ( String title )    {        this.title = title;    }    public void setMessage ( String message )    {        this.message = message;    }}

Builder

package example;/** * @author Created by MadJieJie on 2017/4/17-14:00. * @brief * @attention */public interface Builder{    void setTitle ( String title );    void setMessage ( String message );    Product getProduct ();}

ConcreteBuilder

package example;/** * @author Created by MadJieJie on 2017/4/17-14:01. * @brief * @attention */public class ConcreteBuilder implements Builder{    private Product mProduct = new Product();    @Override    public void setTitle ( String title )    {        mProduct.setTitle(title);    }    @Override    public void setMessage ( String message )    {        mProduct.setMessage(message);    }    @Override    public Product getProduct ()    {        return mProduct;    }}

Director

package example;/** * @author Created by MadJieJie on 2017/4/17-14:00. * @brief * @attention */public class Director{    private final ConcreteBuilder mConcreteBuilder;    public Director ( ConcreteBuilder concreteBuilder )    {        mConcreteBuilder = concreteBuilder;    }        public Director setTitleAndMessage(String title,String message)//construct    {        mConcreteBuilder.setTitle(title);        mConcreteBuilder.setMessage(message);        return this;    }}

Test

    private static void testExample()    {        ConcreteBuilder AConcreteBuilder = new ConcreteBuilder();       //set builder.        Director director = new Director(AConcreteBuilder);         //set director.        director.setTitleAndMessage("MadJieJie","I like you."); //construct        Product AProduct = AConcreteBuilder.getProduct();                   //Only have a product can be quote.        ConcreteBuilder BConcreteBuilder = new ConcreteBuilder();       //set builder.        director = new Director(BConcreteBuilder);        director.setTitleAndMessage("Rain","We are just friend."); //construct        Product BProduct = BConcreteBuilder.getProduct();        AProduct.show();        BProduct.show();    }

协作

这里写图片描述

1.客户创建ConcreteBuilder对象;

2.客户创建Director对象,并将ConcreteBuilder对象赋入;

3.使用导演类引用变量进行构造;

4.通过ConcreteBuilder获得产品类。

Android中的Builder

在Android-V7包中AlertDialog也是使用Builder设计模式,只不过与理论的方式有些不同,使得Builder更为灵活,下面我模仿其中的思路写出上述例子的对话框。

参与者

Controller(控制者):主要负责对部件的构造,控制属性的变化,是对部件真实的操作。

DialogParams:Controller的内部类,含有对话框的属性:title&message,还有将所有不为NULL的属性进行构造的方法(apply(Controller controller)),主要为将Builder构造的部件应用到Controller,进行真实的布置。

Dialog:只能通过Builder生产Dialog的实例(产品),Dialog实例可以通过控制器的实例(mConcroller)来进行对产品的属性重置:setTitle()&setMessage(),也可以进行行为(show()).

Builder:通过对DialogParams的实例引用从而选择性地对部件属性进行构造,然后通过创建方法create()生产Dialog实例,而create()方法会调用applay方法从而将设置的属性真实地布置到Controller上。

Controller

package apply;/** * @author Created by MadJieJie on 2017/4/17-11:56. * @brief * @attention */public class Controller{    public String mTitle;    public String mMessage;    public String getTitle ()    {        return mTitle;    }    public void setTitle ( String title )    {        mTitle = title;    }    public String getMessage ()    {        return mMessage;    }    public void setMessage ( String message )    {        mMessage = message;    }    public static class DialogParams    {        public String mTitle;        public String mMessage;        public void apply ( Controller controller )        {            if ( mTitle != null )            {                controller.setTitle(mTitle);            }            if ( mMessage != null )            {                controller.setMessage(mMessage);            }        }    }}

Dialog

package apply;/** * @author Created by MadJieJie on 2017/1/24-18:37. * @brief * @attention */public class Dialog{    private final Controller mController;    protected Dialog ()    {        mController = new Controller();    }    public Dialog setTitle ( String title )    {        mController.setTitle(title);        return this;    }    public Dialog setMessage ( String message )    {        mController.setMessage(message);        return this;    }    /**     * If object not null ,then it will show.     */    public void show ()    {        if ( mController.getTitle() != null )            System.out.println(mController.getTitle());        if ( mController.getMessage() != null )            System.out.println(mController.getMessage());    }    /**     * Set Builder become inner class.     */    public static class Builder    {        Controller.DialogParams mParams;        public Builder ()        {            mParams = new Controller.DialogParams();        }        public Builder setTitle ( String title )        {            mParams.mTitle = title;            return this;        }        public Builder setMessage ( String message )        {            mParams.mMessage = message;            return this;        }        public Dialog create ()        {            final Dialog dialog = new Dialog();            mParams.apply(dialog.mController);            return dialog;        }    }}

Test

    private static void testApply ()    {        Dialog.Builder builder = new Dialog.Builder();        builder                .setTitle("MadJieJie")                .setMessage("I love you");        Dialog dialog = builder.create();        dialog.show();    }

效果

1.它使得你可以改变一个产品的内部表示

Builder对象提供给导向器一个构造产品的抽象接口。使得构造器(Builder)可以隐藏这个产品的表示和内部结构,达到的封装的目的。

2.它将构造代码和表示代码分开

Builder模式通过封装一个复杂对象的创建和表示方法提高了对象的模块性,即减少了模块间的耦合性。客户不需要知道定义产品内部结构类的所有信息,每个ConcreteBuilder包含创建和装配一个特定产品的所有方法,这些代码只需要写一次;然后不同的Director可以复用它以在相同部件集合的基础上构造不同的Product。

3.它使你可对构造过程更为精细的控制

比如对话框, 有一些我需要标题和信息,有些我只需要标题,有些我只要信息,它能够清晰反映出构造过程。

源码下载

1 0
原创粉丝点击