1. 概述
在生活上,我们经常需要一个指南,按照一定的步骤去完成一件事情,很多符合条件的人都可以按照指南上的步骤去完成这件事情,但是不用关心这些个人是如何完成这些步骤的。这类情况就有点像是设计模式中的生成器模式(Builder)。
2. 生成器模式
定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
生成器模式结构图如下
其中:
- Builder:生成器接口,定义创建一个Product对象所需的各个部件的操作。
- ConcreteBuilder:具体的生成器实现,实现各个部件的创建,并负责组装Product对象的各个部件,同时还提供一个让用户获取组装完成后的产品对象的方法。
- Director: 指导者,也被称为导向者,主要用来使用Builder接口,以一个统一的过程来构建所需要的Product对象。
- Product:产品,表示被生成器构建的复杂对象,包含多个部件。
下面用代码实现一下
(1)先看看生成器的接口定义,示例代码如下:
/**
* 生成器接口,定义创建一个产品对象所需的各个部件的操作
*/
public interface Builder {
/**
* 示意方法,构建某个部件
*/
public void buildPart();
}
(2)再看看具体的生成器实现,示例代码如下:
/**
* 具体的生成器实现对象
*/
public class ConcreteBuilder implements Builder {
/**
* 生成器最终构建的产品对象
*/
private Product resultProduct;
/**
* 获取生成器最终构建的产品对象
* @return 生成器最终构建的产品对象
*/
public Product getResult() {
return resultProduct;
}
public void buildPart() {
//构建某个部件的功能处理
}
}
(3)看看相应的产品对象的接口示意,示例代码如下:
/**
* 被构建的产品对象的接口
*/
public interface Product {
//定义产品的操作
}
(4)再来看看指导者的实现示意,示例代码如下:
/**
* 指导者,指导使用生成器的接口来构建产品的对象
*/
public class Director {
/**
* 持有当前需要使用的生成器对象
*/
private Builder builder;
/**
* 构造方法,传入生成器对象
* @param builder 生成器对象
*/
public Director(Builder builder) {
this.builder = builder;
}
/**
* 示意方法,指导生成器构建最终的产品对象
*/
public void construct() {
//通过使用生成器接口来构建最终的产品对象
builder.buildPart();
}
}
代码实现就到此结束了,下面用个具体实例的来加强理解。
3. 使用生成器模式
在前几年的手机里,诺基亚和三星占了很大的市场份额。大家应该还记得诺基亚的强大,手机一摔,直接分成3块,机身、电池和手机后盖,然后再把它们组装回去,又可以继续用了~~
现在,我就把手机当做(Product),诺基亚和三星手机便是手机的不同实现,而机身、电池和手机后盖就是手机的部件(Part),这些部件是制造商分别生产的。把这三个部件组装在一起,就可以使用该手机了。而组装步骤很简单:
- 将电池装上机身。
- 将手机后盖盖上。
现在就可以用代码来实现一下这个场景。
(1)先是手机的三个组成部件类,这些部件只有一个brand字段代表品牌,其它细节便在此略过了~
1、机身(Body)
/**
* 机身
*/
public class Body {
// 所属品牌
private String brand;
// ..其它细节
public Body(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
}
2、电池(Battery)
/**
* 电池
*/
public class Battery {
// 所属品牌
private String brand;
// ..其它细节
public Battery(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
}
3、手机后盖(BackCover)
/**
* 手机后盖
*/
public class BackCover {
// 所属品牌
private String brand;
//..其它细节
public BackCover(String brand) {
this.brand = brand;
}
public String getBrand() {
return brand;
}
}
(2)手机类(Phone),有三个字段分别对应上面的三个部件类,并提供各自的getter和setter方法
/**
* 手机
*/
public class Phone {
private Body body;//机身
private Battery battery;//电池
private BackCover backCover;//后盖
public void setBody(Body body) {
this.body = body;
}
public void setBattery(Battery battery) {
this.battery = battery;
}
public void setBackCover(BackCover backCover) {
this.backCover = backCover;
}
public Body getBody() {
return body;
}
public Battery getBattery() {
return battery;
}
public BackCover getBackCover() {
return backCover;
}
}
(3)生成器接口,定义了创建一个手机(Phone)对象所需的各个部件的操作
/**
* 生产器接口,定义创建手机所需的各个部件的操作
*/
public interface Builder {
/**
* 构建机身
*/
public void buildBody();
/**
* 构建电池
*/
public void buildBattery();
/**
* 构建后盖
*/
public void buildBackCover();
}
(4)具体生成器的实现,一个是诺基亚(Nokia)的实现,一个是三星(Samsung)的实现
1、诺基亚(Nokia)的生成器实现
/**
* 诺基亚实现生成器对象
*/
public class NokiaBuilder implements Builder{
private Phone phone = new Phone();
/**
* 具体构建诺基亚机身
*/
public void buildBody() {
Body body = new Body("Nokia");
phone.setBody(body);
}
/**
* 具体构建诺基亚电池
*/
public void buildBattery() {
Battery battery = new Battery("Nokia");
phone.setBattery(battery);
}
/**
* 具体构建诺基亚后盖
*/
public void buildBackCover() {
BackCover backCover = new BackCover("Nokia");
phone.setBackCover(backCover);
}
public Phone getPhone() {
return phone;
}
}
2、三星(Samsung)的生成器实现
/**
* 三星实现生成器对象
*/
public class SamsungBuilder implements Builder{
private Phone phone = new Phone();
/**
* 具体构建三星机身
*/
public void buildBody() {
Body body = new Body("Samsung");
phone.setBody(body);
}
/**
* 具体构建三星电池
*/
public void buildBattery() {
Battery battery = new Battery("Samsung");
phone.setBattery(battery);
}
/**
* 具体构建三星后盖
*/
public void buildBackCover() {
BackCover backCover = new BackCover("Samsung");
phone.setBackCover(backCover);
}
public Phone getPhone() {
return phone;
}
}
(5)指导者(Director),指导生成器进行具体的产品构建
public class Director {
/**
* 生成器对象,通过构造方法传进来
*/
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
/**
* 指导生成器构建产品
*/
public void construct(){
//1.构建机身
builder.buildBody();
//2.构建电池
builder.buildBattery();
//3.构建后盖
builder.buildBackCover();
}
}
(6)客户端(Client)来测试一下
public class Client {
public static void main(String[] args) {
// 创建具体的生成器
NokiaBuilder builder = new NokiaBuilder();
// SamsungBuilder builder = new SamsungBuilder();
// 创建指导者,并将生成器传入
Director director = new Director(builder);
// 指导者指导生成器构建产品
director.construct();
// 经过以上步骤,此时生成器中的手机对象便构建完毕
Phone phone = builder.getPhone();
// 将手机各个组件的品牌输出,看看是否一致
System.out.println("机身:" + phone.getBody().getBrand());
System.out.println("电池:" + phone.getBattery().getBrand());
System.out.println("后盖:" + phone.getBackCover().getBrand());
}
}
最终输出结果
机身:Nokia
电池:Nokia
后盖:Nokia
那么到此,生成器模式的使用就结束了,你可以发现,如果不使用生成器模式的话,那么在组装手机的时候,在每个具体的实现里都要重复这几个步骤,而生成器模式可以很好的将这些步骤“外包”给别人(指导者),分工鲜明。
4. 思考生成器模式
我觉得生成器模式最重要的两个角色就是生成器(Builder)和指导者(Director)
- 生成器:生成器定义了一个产品所需的各个部件的构建操作,但是如果它还要负责各个部件组装成一个产品的话,那就有点累了,这样子就不能完全关心自己分内的事情一样。就像是一个老师,除了专门教书外,还要管理学生的生活问题,这样子实在是浪费人才。
- 指导者:指导者知道如何将各个产品的部件组合成一个产品,不管他所接待的生产器给他生成的部件是如何实现的,生成器可以放心地将让指导者去捣鼓它生成的部件。就像是邓爷爷说的“不管白猫黑猫,抓到老鼠就是好猫”,给我一只猫(注意必须是猫哟),不管是黑的白的还是黄的花的,我都会训练它去给你抓老鼠~
不过要注意了,指导者的构建过程必须的统一的、固定不变的,变化的部分还是放在生成器中吧~
以上一部分内容参考至《研磨设计模式》
本文详细介绍了生成器模式的概念、结构及应用案例。通过构建手机的例子,深入浅出地讲解了生成器模式如何将复杂对象的构建过程与表示分离,使同一构建过程可以创建不同的表示。
476

被折叠的 条评论
为什么被折叠?



