前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式:Builder

设计模式:Builder

作者头像
用户1172465
发布2018-01-08 14:17:11
6840
发布2018-01-08 14:17:11
举报
文章被收录于专栏:everhadeverhad

简介

建造者模式(Builder),将一个复杂对象的表示和它的构建分离,这样同样的构造过程可以创建出不同的对象状态。

类图

下面的Product是要创建的对象的目标类型,产品。

  • Builder 创建一个Product对象涉及的操作的抽象接口,定义了Product各个部分的创建方法。
  • Director 使用Builder来构建Product,控制构建过程。
  • ConcreteBuilder 一个具体的构建者。

样例代码

目标类型Robot

假设要构建一个机器人Robot类型的对象:

代码语言:javascript
复制
public class Robot {
    private String head;
    private String arm;
    private String leg;
    private String body;

    // getter & setter 省略

    public String getDescription() {
        return toString();
    }

    @Override
    public String toString() {
        return "Robot{" +
                "head='" + head + '\'' +
                ", arm='" + arm + '\'' +
                ", leg='" + leg + '\'' +
                ", body='" + body + '\'' +
                '}';
    }
}

RobotBuilder

使用RobotBuilder接口(也可以是抽象类)来定义Robot各个部分的设置。

代码语言:javascript
复制
public interface RobotBuilder {
   void setArm();
   void setLeg();
   void setBody();
   void setHead();
}

具体的RobotBuilder

可以定义不同RobotBuilder子类来实现不同的Robot的构建。

BigRobotBuilder

构建一个“Big Robot”的建造器如下:

代码语言:javascript
复制
public class BigRobotBuilder implements RobotBuilder {
    private Robot mRobot;

    public BigRobotBuilder(Robot robot) {
        mRobot = robot;
    }

    @Override
    public void setArm() {
        mRobot.setArm("Big arm");
    }

    @Override
    public void setLeg() {
        mRobot.setLeg("Big leg");
    }

    @Override
    public void setBody() {
        mRobot.setBody("Big body");
    }

    @Override
    public void setHead() {
        mRobot.setHead("Big head");
    }
}

MiniRobotBuilder

构建一个“Mini Robot”的建造器如下:

代码语言:javascript
复制
public class MiniRobotBuilder implements RobotBuilder {
    private Robot mRobot;

    public MiniRobotBuilder(Robot robot) {
        mRobot = robot;
    }

    @Override
    public void setArm() {
        mRobot.setArm("Mini arm");
    }

    @Override
    public void setLeg() {
        mRobot.setLeg("Mini leg");
    }

    @Override
    public void setBody() {
        mRobot.setBody("Mini body");
    }

    @Override
    public void setHead() {
        mRobot.setHead("Mini head");
    }
}

RobotBuildDirector

控制Robot构建过程的指挥者:

代码语言:javascript
复制
public class RobotBuildDirector {
    public void buildRobot(RobotBuilder builder) {
        builder.setBody();
        builder.setArm();
        builder.setHead();
        builder.setLeg();
    }
}

如果构建过程需要严格顺序的话,那么Director来封装具体构建过程是很重要的。

调用代码

创建一个具体的builder,然后执行Director.buildRobot()来完成构建:

代码语言:javascript
复制
void main() {
    Robot robot = new Robot();
    RobotBuildDirector director = new RobotBuildDirector();
    RobotBuilder builder = new BigRobotBuilder(robot);
    director.buildRobot(builder);

    // 显示已构建的robot的详细信息
    Log.println(robot.getDescription());
}

小结

以上的Robot案例展示了builder模式的标准形式。 实际使用中,可能没有抽象Builder和Director控制过程这样的需要。 而是,仅仅希望将包含很多可设置的属性的类型的构建相关的代码与类型本身分开。 而且,设置属性的类往往就作为要配置的类的子类。

下面的实际案例中会说明这点。

实际案例

Diaglog

在Android开发中,AlertDialog类型的构建就使用到了Builder模式,而且是简化了的。

代码语言:javascript
复制
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
AlertDialog dialog = dialogBuilder.setIcon(R.drawable.ic_launcher)
        .setMessage("message")
        .setTitle("Title")
        .setNegativeButton("Cancel", null)
        .create();

内部类AlertDialog.Builder用来对AlertDialog的不同的属性进行设置。 注意到setMessage()、setTitle()等方法都返回AlertDialog.Builder对象本身, 这样就可以以“链式代码”的形式对多个属性进行设置。这样的api很常见,如:

代码语言:javascript
复制
StringBuilder sb = new StringBuilder();
sb.append(1).append(2).append(2);

再如:

代码语言:javascript
复制
SharedPreferences sp = getSharedPreferences("1", MODE_PRIVATE);
sp.edit().putBoolean("1", false)
        .putInt("2", 2)
        .putLong("3", 3L)
        .remove("2")
        .apply();

可以看到,Builder对外暴露实际要使用的AlertDialog的各种属性的设置,而且它可以提供一些默认配置。这样使用者就无需每个属性都去指定。 当调用者完成对AlertDialog的一些方面的定制后,执行create()返回最终的dialog对象。

其它例子

Notification也是:

代码语言:javascript
复制
Notification.Builder builder = new Notification.Builder(this);
        Notification.Action action = null;
        String category = "";
        builder.addAction(action)
                .setCategory(category)
                .setColor(0xff00ff00)
                .setNumber(10086)
                .setGroup("groupKey")
                .build();

其它一些第三方库,或者非Android框架中也有类似Builder模式的大量运用,贵在积累和学习。

总结

可以看到,实际使用中的builder模式和标准的模式组成稍微不同。 很多已知的API中,对构建着模式的使用就是: 将一个包含很多不同属性的对象的设置相关逻辑封装为一个静态内部类去完成。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-01-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 类图
  • 样例代码
    • 目标类型Robot
      • RobotBuilder
        • 具体的RobotBuilder
          • BigRobotBuilder
          • MiniRobotBuilder
        • RobotBuildDirector
          • 调用代码
            • 小结
            • 实际案例
              • Diaglog
                • 其它例子
                • 总结
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档