[Head First设计模式]山西面馆中的设计模式——建造者模式
系列文章
[Head First设计模式]山西面馆中的设计模式——装饰者模式
[Head First设计模式]山西面馆中的设计模式——观察者模式
引言
将学习融入生活中,是件很happy的事情,不会感觉到累。一个感觉:很好玩!挺开心的......
为什么会出现建造者模式?
在软件系统中,有时面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成。
这个复杂的对象的各个部分经常面临剧烈变化,但是将它们组合在一起的算法却相对稳定。
比如:建一所房子,建房子的过程基本不变(算法:画图-地基-建造),但是门窗之类的组建确是易变的。
怎么应对这种变化?
如何提供一种“封装机制“来隔离出”复杂对象的各个部分“的变化,从而保持系统中的”稳定构建算法“不随需求改变而改变,这就是建造者模式。
使用建造者模式的目的?
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
建造者模式定义
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
一步步创建复杂的对象,它允许用户只通过制定复杂对象的类型和内容就可以创建它们,用户不知道内部的具体构建细节。
建造者模式类图

建造者模式参与者
抽象建造者(Builder)
为创建一个产品角色对象的各个部件指定抽象接口。
具体建造者(Conctrete Builder)
实现抽象建造者接口,构造和装配产品的各个部件。
定义并明确它所创建的表示。
提供一个返回这个产品的接口。
指挥者(Director)
构建一个使用抽象建造者接口的对象。
产品角色(Product)
被构建的复杂对象,具体建造者创建该产品的内部表示并定义它的装配过程。
包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
实例分析
场景:lz现在在前台点一份大份量的鸡蛋面,据吃货所知,山西面馆中,对鸡蛋面提供三种的做法,1.普通分量的 2.加2元面的大份量的 3.加一个鸡蛋的营养餐。
分析:
抽象建造者:家传制面秘方(算法),所有鸡蛋面的制作过程均要遵循本秘方,否则是砸自己的招牌啊。
具体的建造者:小康师傅(水平有限,面的多少把握不够,徒弟级别),康师傅(多年砍面技术溶于一身,造就了神般的人物,要砍多少面就多少,不多不少正好),康氏(女人,总比男人更懂得营养,营养师级别人物)
指挥者:收银员,根据order指挥这份面如何来做(是否加量,是否加鸡蛋)。
产品角色:鸡蛋面。
代码实现:
建造者 指定不变的创建过程(算法)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.建造者模式
{
/// <summary>
/// 为创建产品指定相对稳定的算法(步骤)
/// </summary>
public abstract class Builder
{
/// <summary>
/// 水温
/// </summary>
public abstract void WaterTemperature();
/// <summary>
/// 削多少下面
/// </summary>
public abstract void CutTimesWheatflour();
/// <summary>
/// 添加西红柿
/// </summary>
public abstract void AddTomattos();
/// <summary>
/// 添加鸡蛋
/// </summary>
public abstract void AddEggs();
/// <summary>
/// 搅拌
/// </summary>
public abstract void Stir();
/// <summary>
/// 返回
/// </summary>
public abstract Food BuildFood();
}
}
具体建造者
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.建造者模式
{
/// <summary>
/// 建造者模式中的具体建造者 小康师傅类 负责普通鸡蛋面的生产
/// </summary>
public class LittleMasterKang : Builder
{
Food normalFood = new Food();
public override void WaterTemperature()
{
Console.WriteLine("小康师傅:嗯,水温有100℃了,可以下面了");
normalFood.DicFood.Add("汤",);
} public override void CutTimesWheatflour()
{
Console.WriteLine("小康师傅:咔咔.....嗯,够了");
normalFood.DicFood.Add("面",5f);
} public override void AddTomattos()
{
Console.WriteLine("小康师傅:切两个西红柿,咔咔.....放入锅中");
normalFood.DicFood.Add("西红柿",2f);
} public override void AddEggs()
{
Console.WriteLine("小康师傅:鸡蛋");
normalFood.DicFood.Add("鸡蛋",3f);
} public override void Stir()
{
Console.WriteLine("小康师傅:一圈,二圈,三圈....{0}圈,嗯,够了", );
}
/// <summary>
/// 返回食物
/// </summary>
public override Food BuildFood()
{
return normalFood;
}
}
}
LittleMasterKang
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.建造者模式
{
/// <summary>
/// 具体建造者 大师级的康师傅类 用来生产大份量的套餐
/// </summary>
public class MasterKang : Builder
{
Food normalFood = new Food();
public override void WaterTemperature()
{
Console.WriteLine("小康师傅:嗯,水温有100℃了,可以下面了");
normalFood.DicFood.Add("汤", );
} public override void CutTimesWheatflour()
{
Console.WriteLine("康师傅:咔咔.....嗯,够了");
normalFood.DicFood.Add("面(2¥)", 7f);
} public override void AddTomattos()
{
Console.WriteLine("康师傅:切两个西红柿,咔咔.....放入锅中");
normalFood.DicFood.Add("西红柿", 2f);
} public override void AddEggs()
{
Console.WriteLine("康师傅:鸡蛋");
normalFood.DicFood.Add("鸡蛋", 3f);
} public override void Stir()
{
Console.WriteLine("康师傅:一圈,二圈,三圈....{0}圈,嗯,够了", );
}
/// <summary>
/// 返回食物
/// </summary>
public override Food BuildFood()
{
return normalFood;
}
}
}
MasterKang
指挥者
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.建造者模式
{
/// <summary>
/// 收银员类 即建造者模式中的指挥者 根据订单指挥 到底做什么样的面
/// </summary>
public class Cashier
{
public void BuidFood(Builder builder)
{
builder.WaterTemperature();
builder.CutTimesWheatflour();
builder.AddTomattos();
builder.AddEggs();
builder.Stir();
}
}
}
Cashier
产品Food
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.建造者模式
{
/// <summary>
/// 产品类
/// </summary>
public class Food
{
Dictionary<string, double> dicFood; public Dictionary<string, double> DicFood
{
get { return dicFood; }
set { dicFood = value; }
}
public Food()
{
dicFood = new Dictionary<string, double>();
}
private double price;
private string foodName;
public void ShowFood()
{
foreach (KeyValuePair<string, double> item in dicFood)
{
foodName += item.Key + ",";
price += item.Value;
}
string[] food = foodName.TrimEnd(',').Split(',');
//为了显示 按正常的顺序显示
foodName = food[] + food[] + food[] + food[];
Console.WriteLine(foodName + "\t" + price + "¥");
}
}
}
Food
控制台代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Wolfy.建造者模式
{
class Program
{
static void Main(string[] args)
{
//创建指挥者
Cashier director = new Cashier();
//创建普通鸡蛋面的制造者 小康师傅
LittleMasterKang kang = new LittleMasterKang();
director.BuidFood(kang);
Food food = kang.BuildFood();
food.ShowFood();
Console.WriteLine();
//创建大份量鸡蛋面建造者 康师傅
MasterKang k = new MasterKang();
director.BuidFood(k);
Food f = k.BuildFood();
f.ShowFood();
Console.Read();
}
}
}
结果

总结
建造者模式类似于工厂模式,但又有所不同,建造者模式最主要的功能是基本方法的调用顺序的安排,这些基本方法已经实现,而工厂方法则重点是创建,组装顺序则不关心。
使用场景
一是产品类非常复杂,或者产品类中调用顺序不同会产生不同的效果。
二是在对象创建过程中会使用到系统中的一些其他对象这些对象在产品对象的创建过程中不容易得到
参考
http://www.cnblogs.com/ywqu/archive/2010/01/11/1643753.html
[Head First设计模式]山西面馆中的设计模式——建造者模式的更多相关文章
- [Head First设计模式]山西面馆中的设计模式——观察者模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 引言 不知不自觉又将设计模式融入生活了,吃个饭也不得安生,也发现生活中的很多场景,都可以用设计模式来模拟.原来设计模式就在 ...
- [Head First设计模式]山西面馆中的设计模式——装饰者模式
引言 在山西面馆吃鸡蛋面的时候突然想起装饰者这个模式,觉得面馆这个场景跟书中的星巴兹咖啡的场景很像,边吃边思考装饰者模式.这里也就依葫芦画瓢,换汤不换药的用装饰者模式来模拟一碗鸡蛋面是怎么出来的吧.吃 ...
- [Head First设计模式]抢票中的设计模式——代理模式
系列文章 [Head First设计模式]山西面馆中的设计模式——装饰者模式 [Head First设计模式]山西面馆中的设计模式——观察者模式 [Head First设计模式]山西面馆中的设计模式— ...
- js架构设计模式——理解javascript中的MVVM开发模式
理解javascript中的MVVM开发模式 http://blog.csdn.net/slalx/article/details/7856769 MVVM的全称是Model View ViewMod ...
- PHP 实战之设计模式:PHP 中的设计模式
本文主要讨论下Web开发中,准确而言,是PHP开发中的相关的设计模式及其应用.有经验的开发者肯定对于设计模式非常熟悉,但是本文主要是针对那 些初级的开发者.首先我们要搞清楚到底什么是设计模式,设计模式 ...
- 设计模式实战系列之@Builder和建造者模式
前言 备受争议的Lombok,有的人喜欢它让代码更整洁,有的人不喜欢它,巴拉巴拉一堆原因.在我看来Lombok唯一的缺点可能就是需要安装插件了,但是对于业务开发的项目来说,它的优点远远超过缺点. 我们 ...
- 设计模式(五)Builder Pattern建造者模式
在我们日常生活中,如构建一个飞船,一个手机,一栋建筑,都会有非常复杂的组装,这时候应该用到建造者模式 以建造一个飞船为例 案例:造小页飞船 1.飞船各部分元件 package com.littlepa ...
- [Python设计模式] 第13章 造小人——建造者模式
github地址:https://github.com/cheesezh/python_design_patterns 题目1 用程序模拟一个画小人的过程,要求小人要有头,身子,左手,右手,左脚,右脚 ...
- 《大话设计模式》ruby版代码:建造者模式
需求: 画一个小人,有头,有身体,两手两脚即可. 初始代码: # -*- encoding: utf-8 -*- #小人一 puts '这是第一个小人' puts '小人一:头' puts '小人一: ...
随机推荐
- 基于Ubuntu14.04系统的nvidia tesla K40驱动和cuda 7.5安装笔记
基于Ubuntu14.04系统的nvidia tesla K40驱动和cuda 7.5安装笔记 飞翔的蜘蛛人 注1:本人新手,文章中不准确的地方,欢迎批评指正 注2:知识储备应达到Linux入门级水平 ...
- cnless.sh:改进版less,可自动识别GBK编码或UTF-8编码。
#!/bin/bash #功能:让GBK编码的文件可以使用less正常显示中文(自动识别GBK和UTF-8编码) #v0. 在LINUX下,使用UTF-8编码,less UTF-8的文件时显示中文正常 ...
- Linux find命令的用法实践
一.find命令简介 Linux下find命令在目录结构中搜索文件,并执行指定的操作.Linux下find命令提供了相当多的查找条件,功能很强大.由于find具有强大的功能,所以它的选项也很多,其中大 ...
- [django]Django站点admin支持中文显示和输入设置
正文: Django站点admin支持中文输入设置,操作如下: 1 需要确定的你的数据库的client客户端和服务端的编码设置为utf-8,如果不是,请将其设置成utf-8编码,我采用mysql,详情 ...
- 摆脱jquery,用自己的JS库实现ajax功能
可以将下面的代码保存在一个文件里如:myAjax.js,以后在项目中如果觉得jquery那一套很重,就完全可以使用自己的ajax库,不用担心性能和兼容性! /** * 创建ajax请求对象 * @re ...
- LCA 倍增||树链剖分
方法1:倍增 1498ms #include <iostream> #include <cstdio> #include <algorithm> #include ...
- NOIP2013火柴排队[逆序对]
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
- 1.bootstrap练习笔记-导航条
bootstrap练习笔记 1.关于导航栏 官网链接:http://v3.bootcss.com/components/#nav 结构大概是这样的: nav标签标识导航栏 class为navbar ...
- React官网学习笔记
欢迎指导与讨论 : ) 前言 本文主要是笔者在React英文官网学习时整理的笔记.由于笔者水平有限,如有错误恳请指出 O(∩_∩)O 一 .Tutoial 篇 1 . React的组件类名的首字母必须 ...
- 生成 PDF 全攻略【2】在已有PDF上添加内容
项目在变,需求在变,不变的永远是敲击键盘的程序员..... PDF 生成后,有时候需要在PDF上面添加一些其他的内容,比如文字,图片.... 经历几次失败的尝试,终于获取到了正确的代码书写方式. 在此 ...