模板方法模式——在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重写定义算法中的某些步骤。

  

  假如我们有两种咖啡因饮料:茶和咖啡。茶的制作过程为:

  (1)烧水

  (2)用沸水浸泡茶叶

  (3)把茶倒进杯子

  (4)加柠檬

  而咖啡的制作过程为:

  (1)烧水  

  (2)用沸水冲泡咖啡

  (3)把咖啡倒进杯子

  (4)加糖和牛奶

  我们发现两种饮料的制作有类似的过程:

  (1)烧水

  (2)用沸水泡咖啡或茶

  (3)把饮料倒进杯子

  (4)在饮料中加入适当调料

  将(1)(3)在一个抽象基类——咖啡因饮料中定义和实现,而(2)(4)在基类中定义为抽象方法,交由具体的饮料子类去实现,并且基类提供一个方法按一定顺序调用这四个方法以完成饮料的制作。

  抽象基类——咖啡因饮料

 public abstract class CaffeineBeverage
{
public void prepareRecipe()
{
boilWater();
brew();
pourInCup();
if (customerWantsCondiments())
{
addCondiments();
}
}
protected abstract void brew();
protected abstract void addCondiments();
void boilWater()
{
Console.WriteLine("Boiling water");
}
void pourInCup()
{
Console.WriteLine("Pouring in cup");
}
protected virtual bool customerWantsCondiments()//钩子
{
return true;
}
}

CaffeineBeverage

  茶
class Tea : CaffeineBeverage
{
protected override void brew()
{
Console.WriteLine("Steeping in tea");
} protected override void addCondiments()
{
Console.WriteLine("Adding lemon");
} }

Tea

  咖啡
class Coffee : CaffeineBeverage
{
protected override void brew()
{
Console.WriteLine("Dripping Coffee through filter");
}
protected override void addCondiments()
{
Console.WriteLine("Adding Sugar and Milk");
}
}

Coffee

  还可以在基类中定义钩子方法,该方法通过空的或者默认的实现,子类可有以选择性的覆盖该方法。钩子方法可以用于影响抽象基类的算法流程。
  带有钩子的咖啡:钩子用于控制是否加入调料
class CoffeeWithHook : CaffeineBeverage
{ override protected void brew()
{
Console.WriteLine("Dripping Coffee through filter");
}
override protected void addCondiments()
{
Console.WriteLine("Adding Sugar and Milk");
}
protected override bool customerWantsCondiments()
{
string answer = getUserInput();
if (answer.ToLower().StartsWith("y"))
{
return true;
}
else
{
return false;
}
}
private string getUserInput()
{
string answer = null;
Console.WriteLine("Would you like milk and sugar with your coffee(y/n)?");
try
{
answer = Console.ReadLine();
}
catch (System.Exception ex)
{
Console.WriteLine("IO error trtying to read your answer");
}
if (answer==null)
{
return "no";
}
return answer;
}
}

CoffeeWithHook

 class Program
{
static void Main(string[] args)
{
Tea myTea = new Tea();
Coffee myCoffee = new Coffee();
CoffeeWithHook CoffeeHook = new CoffeeWithHook();
myTea.prepareRecipe();
Console.WriteLine("");
myCoffee.prepareRecipe();
Console.WriteLine("");
CoffeeHook.prepareRecipe();
Console.ReadKey();
}
}

Program

设计模式C#实现(一)——模板方法模式的更多相关文章

  1. 设计模式 : Template method 模板方法模式 -- 行为型

      设计模式中,模板模式面向的是方法级别的流程.(不过好像世界上大部分问题,都可以抽象点.抽象点吧,最后抽象到一个方法里面吧.) 1. 一个方法,可以用来描述一个流程,这个流程涉及多个环节,不同环节可 ...

  2. 《Head First 设计模式》学习笔记——模板方法模式

    模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以详细方法以及详细构造函数的形式实现.然后声明一些抽象方法来迫使子类实现剩余的逻辑.不同的子类能够以不同的方式实现这些抽象方法,从而对剩余的逻辑有 ...

  3. C#设计模式之十四模板方法模式(Template Method)【行为型】

    一.引言 “结构型”的设计模式已经写完了,从今天我们开始讲“行为型”设计模式.现在我们开始讲[行为型]设计模式的第一个模式,该模式是[模板方法],英文名称是:Template Method Patte ...

  4. headfirst设计模式(9)—模板方法模式

    前言 这一章的模板方法模式,个人感觉它是一个简单,并且实用的设计模式,先说说它的定义: 模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式.让子类别在不改变算法架构的情况下, ...

  5. 设计模式(22)--Template Method(模板方法模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 模板方法模式是类的行为模式.准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声 ...

  6. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---模板方法模式之CoffeineBeverageWithHook[转]

    模板方法模式定义了一个算法骨架,允许子类对算法的某个或某些步骤进行重写(override).   1   2{<HeadFirst设计模式>之模板方法模式 }   3{ 编译工具: Del ...

  7. C#设计模式(14)——模板方法模式

    1.模板方法模式介绍 提到模板我们经常会想到简历模板/PPT模板等,以简历模板为例,不同的人可以使用一样的简历模板,在填充内容时根据自己的名字/工作经历等填写自己的内容,从而形成不同的简历.在OO中模 ...

  8. js设计模式(七)---模板方法模式

    模板方法模式 模板方法模式是一种只需要继承就可以实现的非常简单的模式. 模板方法模式是由两部分组成,第一部分是抽象父类,第二部分是具体实现的子类, 主要适用在同级的子类具有相同的行为放在父类中实现,而 ...

  9. JS设计模式(8)模板方法模式

    什么是模板方法模式? 定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 主要解决:一些方法通用,却在每一个子类都重新 ...

随机推荐

  1. JavaScript中经典方法

    jQuery()通过name名称获取当前name中value数组 /** 获取input中name属性相同的 value数组 */ function my_array_name(m){ var val ...

  2. Entity FrameWork 增删查改的本质

    之前的文章里面已经说了,EF的增删查改.那时候的修改,删除,只能是先查询出来要修改的数据,再修改,删除...现在来一个改进版的,增删查改. 1.Add static void Add() { //1. ...

  3. MVC应用程序中管理(更新)上传的文件

    实现上传文件功能,有时上传也会操作出错,能让用户有改正有机会,开发上传文件能有更新的功能. 文件上传时,如果是存储于应用程序某一目录的话,在更新时需要了解一些流程,先是删除旧文件,更新数据表相关信息, ...

  4. Python入门笔记(20):Python函数(3):关于lambda

    一.lambda函数 1.lambda函数基础: lambda函数也叫匿名函数,即,函数没有具体的名称,而用def创建的方法是有名称的.如下: """命名的foo函数&q ...

  5. Studio for Winforms FlexGrid: 创建分类汇总

    C1FlexGrid.Subtotal方法可以增加包含普通(非小计)行的汇总数据的分类汇总行. 分类汇总支持分层聚合.例如,如果你的表格包含销售数据,你可能会通过产品.地区和推销员来小计一下以得出总的 ...

  6. 几个gcc的扩展功能

    -finstrument-functions  constructor   destructor __builtin_return_address http://linuxgazette.net/15 ...

  7. js实现向上滚动效果

    源码: <style type="text/css"> #up_zzjs{border:1px solid #ccc;width:170px;height:182px; ...

  8. 【洛谷 p3382】模板-三分法(算法效率)

    题目:给出一个N次函数,保证在范围[l,r]内存在一点x,使得[l,x]上单调增,[x,r]上单调减.试求出x的值. 解法:与二分法枚举中点使区间分成2份不一样,三分法是枚举三分点,再根据题目的情况修 ...

  9. mongodb 基本指令学习

    启动 : 1)创建一个文件夹存放mongodb的数据  启动的时候指定这个文件夹为存储mongodb的存储路径  我的目录是D:\data 2)启动mongodb服务  进入安装mongodb的bin ...

  10. ASP.NET MVC下判断用户登录和授权的方法

    日常开发的绝大多数系统中,都涉及到管理用户的登录和授权问题.登录功能(Authentication),针对于所有用户都开放:而授权(Authorization),则对于某种用户角色才开放. 在asp. ...