设计模式-----Builder模式

Builder模式用于构建复杂的对象,避免构造方法中的大量逻辑,使构造过程与表示分离。适用于参数灵活、复杂对象构建,常见于框架配置。Java中Builder模式通过静态内部类实现,setXXX方法设置属性,build方法构建对象,体现类似“懒加载”特性。

1、什么是Builder模式?
(1)对于复杂的对象,如果只是用构造方法创建的话,构造方法中会存在很多的逻辑,那么我们可以一步步有秩序构建它,从而降低复杂度;
(2)对于复杂的对象,使用者不必知道其内部是如何实现的清下,逐步构造需要的实例对象;
2、什么情况下使用Builder模式?
  (1)将一个复杂对象的构建与它的表示分离,即相同的构造过程可以有不同表示;
  (2)当有多个构造器且需要传入不同的参数表示不同的产品时(即可以弥补工厂模式等无法选择多参数的缺点)
  (3)传入参数情况比较灵活且复杂的情况,或者说一开始不需要明确参数的情况。
  (4)框架中很多Configuration配置都会用到Builder模式。
3、具体使用Builder例子
(1)以前经常通过不同构造器传入不同的参数构造不同复杂的对象,比如我们现在需要一个User的不同情况对象

  • 只有id和name
  • 有id、name、age
  • 有id、name、age、address
public class User {
    private int id;
    private String name;
    private int age;
    private String address;
    
    //不同的构造器传入不同的参数,创造不同的复杂的产品
    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }
    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }
    public User(int id, String name, int age, String address) {
        this.id = id;
        this.name = name;
        this.age= age;
        this.address = address;
    }
    
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}

测试类这样编写:

public class Main {
    public static void main(String[] args) {
        //情况1:id、姓名
        User user = new User(1, "Zhangsan");
        //情况2:id、姓名、年龄
        User user2 = new User(2,"Lisi",22);
        //情况3:id、姓名、年龄、地址
        User user3 = new User(3,"Wangwu",23,"Beijing");
        //情况4:id与年龄不清楚,很容易混淆,必须得查看源码或者文档才能知道哪个参数位置id/年龄
        User user4 = new User(24,"Wangwu",24,"Beijing");
    }
}

OK,这样是没有问题的,但是会有以下弊端:

  • 就好比情况4。当传入的参数很多并且没有说明文档的情况下,之后阅读完源码后才能更好地使用。那么就有可能对源码进行修改,这样就违背了在应用中一个好的设计模块的原则,即设计模式中的开闭原则(Open-Closed Principle, OCP,对修改封闭)
  • 每种情况都得编写一个的构造器,没有一点的灵活度。再比如这里address属性是可选的,可以不传入,那么灵活度同样很低!
    (2)接下来就使用Builder模式创建,注意:Builder主要采用Java静态内部类
/**
 * 利用Builer模式灵活面对复杂对象的创建
 * @author Lijian
 *
 */
public class User2 {
    private int id;
    private String name;
    private int age;
    private String address;
    
    private User2(Builder builder) {
        this.id = builder.id;
        this.name = builder.name;
        this.age = builder.age;
        this.address = builder.address;
    }
    static class Builder{
        private int id;
        private String name;
        private int age;
        private String address;
        //灵活选择参数
        public Builder setId(int id) {
            this.id = id;
            return this;
        }
        public Builder setName(String name) {
            this.name = name;
            return this;
        }
        public Builder setAddress(String address) {
            this.address = address;
            return this;
        }
        public Builder setAge(int age) {
            this.age = age;
            return this;
        }
        //最后build返回User2对象
        public User2 build() {
            return new User2(this);
        }
    }
}

测试类:

public class Main {
    public static void main(String[] args) {
        //通过build创建了User2对象,之后通过setXXX方法可灵活初始化属性,最后build返回对象
        User2 user = new User2.Builder().setId(1).setName("Lijian").setAge(22).build();
        //情况1:id、姓名
        User2 user2 = new User2.Builder().setId(2).setName("Zhangsan").build();
        //情况2:id、姓名、年轻、地址
        User2 user3 = new User2.Builder().setId(2).setName("Lisi").build();
        //情况3:id与age很明显能区分
        User2 user4 = new User2.Builder().setId(23).setAge(23).build();
    }
}

通过setXXX()方法灵活选择参数,最后build()方法“闭合”返回对象。很适用于复杂对象的创建,此处让我想起Java8新特性中的Stream API的一个特点:懒加载。是的,有点“懒加载”的味道,不需要立马指定属性,也不会立马生效,之后最后的操作build()才会生效!

了解更多java知识,加qq群免费获得java进阶学习资料,QQ群:1007476384

<think>我们正在讨论Android开发中的Builder设计模式。根据引用内容,Builder模式主要用于构建复杂对象,通过链式调用设置参数,最后通过build方法创建对象实例。实现细节包括:1.私有化目标类的构造方法,使其只能通过内部Builder类构建。2.静态内部类Builder,它拥有与目标类相同的字段,并提供设置这些字段的方法(每个方法返回Builder自身以实现链式调用)。3.Builder类提供一个build方法,在该方法中调用目标类的私有构造方法(将Builder自身作为参数传入),在目标类的构造方法中完成字段的复制。4.目标类一旦创建,其参数不可更改(即不可变)。在Android中,AlertDialog就是使用Builder模式的经典例子。现在,我们按照用户要求,详细说明Builder模式的使用与实现。</think>### Android Builder设计模式的使用与实现 Builder设计模式是一种创建型模式,用于**分步构建复杂对象**,特别适用于参数众多或配置灵活的场景。在Android开发中,Builder模式被广泛应用于对话框创建、网络请求配置等场景。 #### 一、核心实现原理 1. **私有化构造方法** 目标类的构造方法设为私有,禁止直接实例化。 ```java public class User { private final String name; // final确保不可变 private final int age; private User(Builder builder) { // 私有构造器 this.name = builder.name; this.age = builder.age; } } ``` 2. **静态内部Builder类** 作为构建桥梁,持有与目标类相同的字段: ```java public static class Builder { private String name; private int age; public Builder setName(String name) { this.name = name; return this; // 返回自身实现链式调用 } public Builder setAge(int age) { this.age = age; return this; } public User build() { return new User(this); // 调用私有构造器 } } ``` #### 二、Android经典应用:AlertDialog ```java // 使用示例 AlertDialog dialog = new AlertDialog.Builder(context) .setTitle("警告") .setMessage("确认删除?") .setPositiveButton("确定", (d, which) -> { /* 逻辑 */ }) .setNegativeButton("取消", null) .create(); // 最终构建对象 ``` **实现解析**(参考引用[2][4]): 1. `AlertDialog`构造器私有化,只能通过`Builder`构建 2. `Builder`的每个set方法返回自身,支持链式调用 3. `create()`方法调用`AlertDialog`私有构造器并传入配置参数 4. 最终通过`show()`将Dialog添加到WindowManager[^4] #### 三、自定义Builder模式实现 以构建用户对象为例: ```java public class User { private final String name; private final int age; private final String email; private User(Builder builder) { this.name = builder.name; this.age = builder.age; this.email = builder.email; } public static class Builder { private String name; private int age; private String email = ""; // 默认值 public Builder setName(String name) { this.name = name; return this; } public Builder setAge(int age) { if (age < 0) throw new IllegalArgumentException("年龄无效"); this.age = age; return this; } public Builder setEmail(String email) { this.email = email; return this; } public User build() { if (name == null) throw new IllegalStateException("名称不能为空"); return new User(this); } } } // 使用示例 User user = new User.Builder() .setName("张三") .setAge(30) .setEmail("zhang@example.com") .build(); ``` #### 四、设计优势 1. **参数解耦**:分离对象构建与参数设置(引用[1]) 2. **链式调用**:提升代码可读性(引用[6]) 3. **对象不可变**:build()后字段final确保线程安全 4. **参数校验**:可在build()方法中集中校验 5. **灵活扩展**:支持可选参数和默认值 #### 五、适用场景 1. 需创建含多个可选参数的对象 2. 要求对象创建后不可修改(不可变对象) 3. 需要分步构建复杂配置(如Retrofit.Builder) 4. 替代冗长的多参数构造方法 > **关键点**:Builder模式通过内部类封装构建逻辑,既保证对象创建的灵活性,又维持了目标类的不可变性。在Android中,除了对话框外,Glide图片加载框架、Retrofit网络库等都广泛采用此模式[^2][^3]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值