[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 '小人一: ...
随机推荐
- 012.对netmap API的解读
一.简要说明: 1.netmap API主要为两个头文件netmap.h 和netmap_user.h ,当解压下载好的netmap程序后,在./netmap/sys/net/目录下,本文主要对这两个 ...
- Spring AOP支持的AspectJ切入点语法大全
原文出处:http://jinnianshilongnian.iteye.com/blog/1420691 Spring AOP支持的AspectJ切入点指示符 切入点指示符用来指示切入点表达式目的, ...
- nginx转发会 默认忽略 headers 中name带”_”的
昨天遇到一个很蛋疼的问题,在提供的一个 http api中,有定义了一个"X_AUTH_TOKEN"自定义head,可是请求这个api时带上"X_AUTH_TOKEN&q ...
- 烂泥:openvpn tun模式下客户端与内网机器通信
本文由秀依林枫提供友情赞助,首发于烂泥行天下 前两篇文章我们介绍了有关openvpn的搭建与配置文件的讲解,这篇文章我们再聊介绍下,在tun模式下openvpn客户端如何与内网机器通信的问题. 一.实 ...
- [HTML表格]在databases显示行的附加信息
模板代码: <!-- DataTables CSS --> <link rel="stylesheet" href="{% static 'DataTa ...
- EF6 Create Different DataContext on runtime(运行时改变连接字符串)
引言 在使用EF时,有时我们需要在程序运行过程中动态更改EF的连接字符串,但不幸的时EF是否对 ConfigurationManager.RefreshSection("xxx" ...
- c++中this指针的用法
1. this指针的用处: 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果.this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将 ...
- POJ1947 Rebuilding Roads[树形背包]
Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 11495 Accepted: 5276 ...
- java读取excel文件
package com.execl; import java.io.File; import java.io.FileInputStream; import java.io.IOException; ...
- 简单了解ICMP协议
ping命令是什么协议? 维基百科: ping是一种电脑网络工具,用来测试数据包能否通过IP协议到达特定主机.ping的运作原理是向目标主机传出一个ICMP echo@要求数据包,并等待接受echo回 ...