设计模式解密(6) - 建造者模式

1、简介

定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

英文:Builder

类型:创建类模式

2、原理及组成

引:类图

四个要素

  • 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量。在本类图中,产品类是一个具体的类,而非抽象类。实际编程中,产品类可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成。
  • 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现。这样更容易扩展。一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品。
  • 建造者:实现抽象类的所有未实现的方法,具体来说一般是两项任务:组建产品;返回组建好的产品。
  • 导演类:负责调用适当的建造者来组建产品,导演类一般不与产品类发生依赖关系,与导演类直接交互的是建造者类。一般来说,导演类被用来封装程序中易变的部分。

3、实例引入

背景:模拟生产各种笔(这里假设笔的零件生产是有顺序的:笔芯 -> 笔壳 -> 组装)

创建抽象产品类 -- 笔

package com.designpattern.builder;
/**
 * 笔  -- 抽象产品类
*/
public abstract class Pen {
	/**笔芯**/
	private String cartridge;
	/**外壳**/
	private String shell;

	public String getCartridge() {
		return cartridge;
	}
	public void setCartridge(String cartridge) {
		this.cartridge = cartridge;
	}
	public String getShell() {
		return shell;
	}
	public void setShell(String shell) {
		this.shell = shell;
	}
}

创建抽象建造者(笔builder) 接口

package com.designpattern.builder;
/**
 * 抽象建造者  -- 笔builder
*/
public abstract interface PenBuilder {
	/**
	 * 生产笔芯
	 */
	abstract void buildCartridge();
	/**
	 * 生产外壳
	 */
	abstract void buildShell();
	/**
	 * 组装笔
	 */
	abstract Pen buildPen();
}

创建具体产品类(圆珠笔)

package com.designpattern.builder;
/**
 * 具体产品类 -- 圆珠笔
*/
public class BallpointPen extends Pen{
	public BallpointPen(){
		System.out.println("生产组装圆珠笔");
	}
}

创建具体产品类(画笔)

package com.designpattern.builder;
/**
 * 具体产品类 -- 画笔
*/
public class BrushPen extends Pen{
	public BrushPen(){
		System.out.println("生产组装画笔");
	}
}

创建建造者(具体)  -- 圆珠笔builder

package com.designpattern.builder.impl;

import com.designpattern.builder.BallpointPen;
import com.designpattern.builder.Pen;
import com.designpattern.builder.PenBuilder;

/**
 * 建造者(具体)  -- 圆珠笔builder
*/
public class BallpointPenBuilder implements PenBuilder{

	Pen pen;
	public BallpointPenBuilder(){
		pen = new BallpointPen();
	}

	@Override
	public void buildCartridge() {
		pen.setCartridge("圆珠笔笔芯");
	}

	@Override
	public void buildShell() {
		pen.setShell("圆珠笔外壳");
	}

	@Override
	public Pen buildPen() {
		return pen;
	}

}

创建建造者(具体)  -- 画笔builder

package com.designpattern.builder.impl;

import com.designpattern.builder.BrushPen;
import com.designpattern.builder.Pen;
import com.designpattern.builder.PenBuilder;

/**
 * 建造者(具体)  -- 画笔builder
*/
public class BrushPenBuilder implements PenBuilder{

	Pen pen;
	public BrushPenBuilder(){
		pen = new BrushPen();
	}

	@Override
	public void buildCartridge() {
		pen.setCartridge("画笔笔芯");
	}

	@Override
	public void buildShell() {
		pen.setShell("画笔外壳");
	}

	@Override
	public Pen buildPen() {
		return pen;
	}

}

创建导演类  Director

package com.designpattern.builder;
/**
 * 导演类  Director
*/
public class PenDirector {

	public Pen constructPen(PenBuilder pen_builder){
		//生产笔芯
		pen_builder.buildCartridge();
		//生产外壳
		pen_builder.buildShell();
		//组装笔
		return pen_builder.buildPen();
	}
}

下面测试一下

package com.designpattern.builder;

import com.designpattern.builder.impl.BallpointPenBuilder;
import com.designpattern.builder.impl.BrushPenBuilder;

/**
 * 测试
*/
public class Test {
	public static void main(String[] args) {
		PenDirector director = new PenDirector();
		Pen ballpointpen = director.constructPen(new BallpointPenBuilder());
		Pen brushpen = director.constructPen(new BrushPenBuilder());
	}
}

结果:

生产组装圆珠笔
生产组装画笔

4、解决的问题

笔的种类不止这几种,还有很多,使用建造者模式可以将一类产品的构建过程和细节进行封装(实现代码的复用)与产品的表示进行分离,即:使用同样的构建过程可以创建不同的产品;

在各个建造者类,只需定义生产零件方法,具体的生产顺序定义在导演类中;

5、优缺点

优点:

  (封装性)建造者模式的封装性很好。使用建造者模式可以有效的封装变化,在使用建造者模式的场景中,一般产品类和建造者类是比较稳定的,因此,将主要的业务逻辑封装在导演类中对整体而言可以取得比较好的稳定性。

  (扩展性)建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,基本上不用修改之前已经测试通过的代码,因此也就不会对原有功能引入风险。

  (便于控制细节风险)由于具体的建造者是独立的,因此可以对建造者过程逐步细化,而不对其他的模块产生任何影响。

缺点:

  建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。

  如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

6、应用场景

  建造者模式 --- 建造具有具体细节的产品

  1、需要生成的产品对象有复杂的内部结构,这些产品对象具备共性。

  2、需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。

  ........

7、与其他模式对比

  我们可以看到,建造者模式与工厂模式是极为相似的,总体上,建造者模式仅仅只比工厂模式多了一个“导演类”的角色。在建造者模式的类图中,假如把这个导演类看做是最终调用的客户端,那么图中剩余的部分就可以看作是一个简单的工厂模式了。

  这里先回归一下定义:

      工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类;

      建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示;

  与工厂模式相比,建造者模式一般用来创建更为复杂的对象,因为对象的创建过程更为复杂,因此将对象的创建过程独立出来组成一个新的类——导演类。也就是说,工厂模式是将对象的全部创建过程封装在工厂类中,由工厂类向客户端提供最终的产品;而建造者模式中,建造者类一般只提供产品类中各个组件的建造,而将具体建造过程交付给导演类。由导演类负责将各个组件按照特定的规则组建为产品,然后将组建好的产品交付给客户端。

  工厂模式一般都是创建一个产品,注重的是把这个产品创建出来就行,只要创建出来,不关心这个产品的组成部分。

  建造者模式也是创建一个产品,但是不仅要把这个产品创建出来,还要关心这个产品的组成细节, 组成过程。

8、总结

  建造者模式最主要功能是基本方法的调用顺序安排,也就是这些基本方法已经实现了;

  而工厂方法则重点是创建,你要什么对象就创造一个对象出来,组装顺序则不是他关心的。

  PS:建造模式的关键是导演角色,这个角色掌握了零件对象的状态和产品的整体组装蓝图。没有了这个角色,建造模式就不是建造模式。当然,导演角色可以同时持有很多种蓝图,按照需要给出完全不同的组装结果。

  PS2:源码地址   https://github.com/JsonShare/DesignPattern/tree/master

时间: 2024-11-09 00:46:54

设计模式解密(6) - 建造者模式的相关文章

设计模式学习04—建造者模式

一.动机与定义 创建对象时,我们知道可以使用工厂方式来创建,使调用者和具体实现解耦,但是有一种情况,当要创建的多个对象之间重复性较大,只有创建步骤.组装顺序或者内部构件不同时,工厂模式就需要进一步的演化了,如我们去KFC,有很多种套餐,比如套餐1(薯条+可乐+汉堡),套餐2(鸡肉卷+薯条+可乐),这个套餐就是我们要获取的复杂对象,那么程序如何创建出这种对象呢. 我们看到套餐的内容很多是一样的,那么我们是不是可以考虑将创建单个食品(如鸡肉卷.可乐等)方法提取出来,使用单独一个类协调这些食品的组合比

设计模式学习笔记-建造者模式

一.概述 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示: 二.模式中的角色 Builder:为创建一个Product对象的各个部件指定抽象接口: ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件:定义并明确它所创建的表示:提供一个检索产品的接口: Director:构造一个使用Builder接口的对象: Product:表示被构造的复杂对象,ConcreteBuilder创建该产品的内部表示并定义它的装配过程:包含定义组成部件的类,

设计模式--17、建造者模式

[转]建造者模式 一个人活到70岁以上,都会经历这样的几个阶段:婴儿,少年,青年,中年,老年.并且每个人在各个阶段肯定是不一样的呀,我觉得可以说世界上不存在两个人在人生的这5个阶段的生活完全一样,但是活到70岁以上的人,都经历了这几个阶段是肯定的.实际上这是一个比较经典的建造者模式的例子了. 1.初识建造者模式 建造者模式实际上是常用的设计模式.顾名思义,builder的意思是建造者或者建筑工人,谈到建造自然会想到楼房.楼房是千差万别的,楼房的外形.层数.内部房间的数量.房间的装饰等等都不一样,

设计模式之禅——建造者模式

建造者模式定义: 建造者模式也叫做生成器模式--将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.) 例子:我们要生产一个简单车模(汽车模型),汽车模型要有启动.停止.引擎发出声音.喇叭响等功能.现在我要让用户根据自己的喜好来选择这些功能的顺序~(接着上一篇模板方法模式的例子) 我们做出了下面的设计,见UML图 见代码 //汽车模型的抽象类 public abstract class CarModel{ //sequence就是客户要求执行的方法的顺序 private A

Android设计模式--建造者模式

回头看自己写的东西,在关于Android自定义控件时,写的代码适用性比较高,但是看上去没有什么技术含量,所以在学习设计模式的时候,想想有些东西是否能够改进,比如说: 自定义Dialog是Android应用必须的,系统的控件实在是太难看了: 在构建中,完全是,new完对象之后,需要什么构建什么,这样写没有问题,可读性也还行,就是看上去不咋的. 以下是小部分代码片段: package com.example.demo.Builder; /** * * @author qubian * @data 2

Java设计模式百例 - 建造者模式

本文源码见:https://github.com/get-set/get-designpatterns/tree/master/builder 建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象,这种类型的设计模式属于创建型模式.建造模式可以将一个复杂对象的内部组成部分,与该对象本身的创建分离开来,从而使得复杂对象的组装更灵活. 文绉绉的话不宜多说,其实这种模式还是挺常见的: * 比如我们在订手机套餐的时候,无论是自选还是电信公司配置好的,通常一个套餐包括

我的设计模式:从模版设计模式谈到建造者模式

1.模版设计模式  TemplateMethod Pattern 问题:创建模型,如何处理更好?有共性有异性,共性放在哪里(abstract)?异性放在哪里(实现)? 缺陷:暴露方法好吗?protected保护起来    方法不会被子类继承修改final更好 概念:模版中的方法(抽象方法.具体方法.钩子方法) 模版模式:重写父类的方法,再调用父类的方法产生不同的结果 具体方法一般体现在调用其他方法的顺序上 模版模式一定是继承来的 2.建造者模式  Builder Pattern 问题升级:继续添

《设计模式》之建造者模式(Builder)

仅供自己参考,因初次,有很多东西都只是我自己的理解,如想学习请找下一家. 1.简介 是一种对象构建的设计模式,他可以将复杂的建造过程抽象出来,使这个抽象过程的不同实现方法可以构造出不同表现的对象. 优点:建造代码与表示代码分离,有偶遇建造者隐藏了该产品是如何组装的. 2.自己的理解 理解不了. 3.盗来的解释 建造者模式实际上是常用的设计模式.顾名思义,builder的意思是建造者或者建筑工人,谈到建造自然会想到楼房.楼房是千差万别的,楼房的外形.层数.内部房间的数量.房间的装饰等等都不一样,但

java常用设计模式四:建造者模式

1.定义 是一种对象构建的设计模式,它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象. 产品类:一般是一个较为复杂的对象,也就是说创建对象的过程比较复杂,一般会有比较多的代码量.产品类可以是一个具体的类,也可以是由一个抽象类与它的不同实现组成,也可以是由多个抽象类与他们的实现组成. 抽象建造者:引入抽象建造者的目的,是为了将建造的具体过程交与它的子类来实现.这样更容易扩展.一般至少会有两个抽象方法,一个用来建造产品,一个是用来返回产品.

Java设计模式14:建造者模式

什么是建造者模式 发现很多框架的源码使用了建造者模式,看了一下觉得挺实用的,就写篇文章学习一下,顺便分享给大家. 建造者模式是什么呢?用一句话概括就是建造者模式的目的是为了分离对象的属性与创建过程,是的,只要记住并理解红字的几个部分,建造者模式你就懂了. 为什么需要建造者模式 建造者模式是构造方法的一种替代方案,为什么需要建造者模式,我们可以想,假设有一个对象里面有20个属性: 属性1 属性2 ... 属性20 对开发者来说这不是疯了,也就是说我要去使用这个对象,我得去了解每个属性的含义,然后在