研磨设计模式(七)生成器模式
2016-12-20 18:06
417 查看
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)生成器:生成器定义了一个产品所需的各个部件的构建操作,但是如果它还要负责各个部件组装成一个产品的话,那就有点累了,这样子就不能完全关心自己分内的事情一样。就像是一个老师,除了专门教书外,还要管理学生的生活问题,这样子实在是浪费人才。
指导者:指导者知道如何将各个产品的部件组合成一个产品,不管他所接待的生产器给他生成的部件是如何实现的,生成器可以放心地将让指导者去捣鼓它生成的部件。就像是邓爷爷说的“不管白猫黑猫,抓到老鼠就是好猫”,给我一只猫(注意必须是猫哟),不管是黑的白的还是黄的花的,我都会训练它去给你抓老鼠~
不过要注意了,指导者的构建过程必须的统一的、固定不变的,变化的部分还是放在生成器中吧~
以上一部分内容参考至《研磨设计模式》
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- 设计模式---状态模式在web前端中的应用
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用