设计模式(四):通过做蛋糕理解构建模式及Android中的变种
之前的文章介绍了抽象工厂模式,本文介绍另外一种创建型的设计模式,构建者模式(Builder Pattern)。
什么是构建者模式呢?
建造者模式是设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。1
上面的描述有点抽象,所以大白话描述一下。
- 构建者模式的目的是为了构建一个复杂的对象
- 复杂的通俗理解就是,可以以不同的参数创建同一类型的不同对象。
- 和其他创建型模式不同的地方,构建者模式强调过程,是一步一步构建的,和现实当中建房子是一样的。
什么时候用构建者模式?
其实,就在于配置。
以蛋糕店做蛋糕为例子说明。
无论一个蛋糕长什么样子,做蛋糕的大体流程都差不多。
但是顾客的要求,却不一样。
比如有人喜欢白色的奶油,有人喜欢粉色的奶油。
有人喜欢加巧克力,有人不喜欢加。
有人喜欢绘制图案,有人喜欢绘制文字。
有人喜欢猕猴桃,有人喜欢
抽象工厂模式强调的是不同工厂不同生产线产生不同的产品。
构建者模式更加强调同一家工厂同一生产线在创建过程动态配置最终生成不同的产品,这就是所谓的对象不同表示。
构建者的传统表示
- Builder 是一个抽象类或者接口,定义了产品构建的通用过程
- ConcreteBuiler 是 Builder 的实现类,提供了创建 Product 的接口。
- Product 要创建的对象类型
- Director 创建使用 Builder 的对象。
Builder 的 Java 代码示例
首先定义产品
Product.java
public class Product { public int level; public String color; public String text; public String fruit; public Product(){} @Override public String toString() { // TODO Auto-generated method stub return "A cake with " + level + " level,"+" a great "+color+" cream,"+" some "+fruit+" and the drawing text is :"+text; } }
在产品中定义了相关的属性,现在要定义 Builder。
先定义一个抽象类 CakeBuilder 代表蛋糕的创建器
CakeBuilder.java
public abstract class CakeBuilder { public abstract void buildCake(int level); public abstract void buildCream(String color); public abstract void buildText(String text); public abstract void buildFruit(String type); public abstract Product getCake(); }
我们再定义 CakeBuilder 的实现类
ConcreteCakeBuilder.java
public class ConcreteCakeBuilder extends CakeBuilder { private Product cake = new Product(); public ConcreteCakeBuilder(){}; public void buildCake(int level){ cake.level = level; } public void buildCream(String color){ cake.color = color; } public void buildText(String text){ cake.text = text; } public void buildFruit(String type){ cake.fruit = type; } public Product getCake(){ return cake; } }
Builder 只是个执行角色,它需要指导,指导者是 Director,所以,我们还需要定义 Director。
Director.java
public class Director { public void makeCake(CakeBuilder builder) { builder.buildCake(3); builder.buildCream("pink"); builder.buildText("Happy birthday,frank is better!"); builder.buildFruit("mango"); } }
Director 定义了 Builder 工艺的细节。上面的代码表示要做 3 层粉色奶油的蛋糕,水果是芒果,上面有指定字迹。
现在,编写测试 Demo
BuilderDemo.java
public class BuilderDemo { public static void main(String[] args) { Director director = new Director(); ConcreteCakeBuilder builder = new ConcreteCakeBuilder(); director.makeCake(builder); Product cake = builder.getCake(); System.out.println(cake.toString()); } }
运行结果如下:
A cake with 3 level, a great pink cream, some mango and the drawing text is :Happy birthday,frank is better!
构建模式中的表示和构建
如果,我们想要不一样的蛋糕,我们需要定义另外一种 Director,在它的 makeCake 中定义不同的细节,这就是对象的表示。
如果,我们要改变做蛋糕的工艺,我们可以定义另外一种 Builder,它代表了对象的构建过程。
而如构建者模式定义,这个模式就是为了将对象的构建和表示分离,从而创建复杂的对象。
Android 中的构建者
Android 中用的最多的构建者模式是用于创建对话框,我们在 Android 9.0 源码中搜索相关代码,发现 Builder 用的非常广。2
我挑选了 Person 对象分析。
Person.java
public final class Person implements Parcelable { @Nullable private CharSequence mName; @Nullable private Icon mIcon; @Nullable private String mUri; @Nullable private String mKey; private boolean mIsBot; private boolean mIsImportant; private Person(Builder builder) { mName = builder.mName; mIcon = builder.mIcon; mUri = builder.mUri; mKey = builder.mKey; mIsBot = builder.mIsBot; mIsImportant = builder.mIsImportant; } /** Creates and returns a new {@link Builder} initialized with this Person's data. */ public Builder toBuilder() { return new Builder(this); } /** Builder for the immutable {@link Person} class. */ public static class Builder { @Nullable private CharSequence mName; @Nullable private Icon mIcon; @Nullable private String mUri; @Nullable private String mKey; private boolean mIsBot; private boolean mIsImportant; /** Creates a new, empty {@link Builder}. */ public Builder() { } private Builder(Person person) { mName = person.mName; mIcon = person.mIcon; mUri = person.mUri; mKey = person.mKey; mIsBot = person.mIsBot; mIsImportant = person.mIsImportant; } @NonNull public Person.Builder setName(@Nullable CharSequence name) { this.mName = name; return this; } @NonNull public Person.Builder setIcon(@Nullable Icon icon) { this.mIcon = icon; return this; } public Person.Builder setKey(@Nullable String key) { mKey = key; return this; } public Person.Builder setImportant(boolean isImportant) { mIsImportant = isImportant; return this; } public Person.Builder setBot(boolean isBot) { mIsBot = isBot; return this; } /** Creates and returns the {@link Person} this builder represents. */ @NonNull public Person build() { return new Person(this); } } }
和文章前面讲到 Builder 不同的是,Android 中 Builder 更能体现过程。
Builder 是 Product 中的静态类,然后 Android 中的 Builder 不需要 Director。
它将 Director 的行为通过链式调用替代了。
我们仔细看
public Person.Builder setImportant(boolean isImportant) { mIsImportant = isImportant; return this; } public Person.Builder setBot(boolean isBot) { mIsBot = isBot; return this; }
这一类 setXXX() 方法返回的都是 Builder 本身,也就是同一个 Builder,所以很容易去掉 Director 。比如,创建 Person 我们可以通过如下代码:
Person p = new Person.Builder() .setImportant(true) .setBot(false) .setName("frank") .build();
大家看看,更喜欢 Android 这种改良式呢?还是传统的构建者模式?
参考
frank909 CSDN认证博客专家 CV(computer vision) 爱阅读的程序员,专注于技术思考和分享。关注架构设计、Android 开发、AI、数学、自动驾驶领域,个人公号:Frankcall- Android模板设计模式之 - 构建整个应用的BaseActivity
- 设计模式-职责链/责任链模式(Chain of Responsibility)分析理解和在Android的应用
- Android设计模式理解(mvc mvp mvvm)
- Android模板设计模式之 - 构建整个应用的BaseActivity
- android相关的设计模式理解
- Android开发中的设计模式实践理解(一)
- Android设计模式——Builder模式 -- 助于理解所有 类似NotificationCompat.Builder [*.Builder] 模式调用
- 从模式角度理解Android架构设计-Facade模式
- 个人理解的Android设计模式之观察者模式
- 关于android的设计模式---MVP的个人理解
- Java设计模式一:策略模式,通过案例理解
- 设计模式-装饰者模式(Decorator)理解和在Android中的应用
- Android--MVP设计模式的理解和总结
- Android 设计模式之MVC,从一个实例中来理解MVC
- 通过C++和python场景实例理解装饰器设计模式。
- 对Android中设计模式MVC,MVP,MVVM的简单理解
- 实验2:升级《知识测试》理解Android设计模式
- 通过C++程序示例理解设计模式中的外观模式
- C# 通过 Observer观察者 设计模式 来理解 抽象类 和 接口 应用在什么地方
- Android MVP设计模式的理解