设计模式-3-建造者模式(Builder Pattern)

折月煮酒 提交于 2020-03-02 19:12:15

建造者模式(Builder Pattern) ,将一个复杂对象的构建和它的表示分离,使得同样的创建过程可以创建不同的表示。在Android 中也是非常的常见的,比如:

 /**
  * 给宝贝拨打电话
  * 
  * @param no
  */
 private void CallBaby() {
  new AlertDialog.Builder(getActivity())   
  .setTitle(R.string.call_baby)  
  .setMessage(R.string.call_baby_tips)  
  .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
   @Override
   public void onClick(DialogInterface arg0, int arg1) {
    Intent intent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:"+babyListBean.getFullPhone()));  
    startActivity(intent);  
   }
  })  
  .setNegativeButton(R.string.no, null)  
  .show(); 
 }

AlertDialog 的Builder通过setTitle(),setMessage(),setxxButton等方法在create()中构造出一个   AlertDialogInstance对象。然后客户可以把把AlertDialogInstance对象show出去。UML 表示如下:

 

《Effective Java》P9 第二条:遇到多个构造器参数时候要考虑用构造器(为了对比又要设计工厂方法)

使用Builder模式来替代多参数构造函数是一个比较好的实践法则。

 

我们常常会面临编写一个这样的实现类(假设类名叫MemberContact,是关于会员资料的),这个类拥有多个构造函数,

MemberContact(String name,String phone);

MemberContact(String name, String phone,int age);

MemberContact(String name, String phone,int age, String address);

MemberContact(String name, String phone,int age, String address, int cardID);

MemberContact(String name, String phone,int age, String address, int cardID, type ...);

这样一系列的构造函数主要目的就是为了提供更多的客户调用选择,以处理不同的构造请求。这种方法很常见,也很有效力,但是它的缺点也很多。类的作者不得不书写多种参数组合的构造函数,而且其中还需要设置默认参数值,这是一个需要细心而又枯燥的工作。

其次,这样的构造函数灵活性也不高,而且在调用时你不得不提供一些没有意义的参数值,例如,MemberContact("Anylife","10086" ,-1),显然年龄为负数没有意义,但是你又不的不这样做,得以符合Java的规范。如果这样的代码发布后,后面的维护者就会很头痛,因为他根本不知道这个-1是什么含义。对于这样的情况,就非常适合使用Builder模式。Builder模式的要点就是通过一个代理来完成对象的构建过程。这个代理职责就是完成构建的各个步骤,同时它也是易扩展的。下面是改写自Effective Java里面的一段代码:

 

/**
 * 
 * 
 * @author Anylife.zlb@gmail.com
 *
 */
public class MemberContact {
    private final String name;
    private final String phone;   //一个会员的姓名和电话号码是必填项目
    private final int    age;
    private final int    safeID;
    private final String address;
//  private final type   params...
    /**
     * 私有构造方法,在class Builder 中完成Build 后            
     * return new DoDoContact(Builder instance);
     * 有点代理的感觉哈
     * 
     * @param b
     */
    private MemberContact(Builder b) {
        age = b.age;
        safeID = b.safeID;
        name = b.name;
        address = b.address;
        phone = b.phone;
    }
    
    
//    public int getAge() {
//        return age;
//    }
// 
//    public int getSafeID() {
//        return safeID;
//    }
// 
//    public String getName() {
//        return name;
//    }
// 
//    public String getAddress() {
//        return address;
//    }
   
    public static class Builder {
        private String name    = null;
        private String phone = null;
        
        private int    age     = 0;
        private int    safeID  = 0;
        private String address = null;
        public MemberContact build() { // 构建,返回一个新对象
            return new MemberContact(this);
        } 
        
        public Builder(String name,String phone) {
            this.name = name;//这两个是必填的参数
             this.phone=phone;

        }
        
        public Builder phone(String val) {
         phone = val;
            return this;
        }
 
        public Builder age(int val) {
            age = val;
            return this;
        }
 
        public Builder safeID(int val) {
            safeID = val;
            return this;
        }
 
        public Builder address(String val) {
            address = val;
            return this;
        }
 
    }
}

 

 随心所欲的调用:
//    MemberContact mc1 = new MemberContact.Builder("who").phone(110).address("shenzhen").build();

//    MemberContact mc2 = new MemberContact.Builder("anylife").phone(1882656).age(10).address("beijing").build();

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!