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

  

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

  (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. MySQL5中大数据错误:Packet for query is too large (****** > ******). You can change this value on the server by setting the max_allowed_packet' variable.;

    使用的MySQL数据库版本:5.5 插入或更新字段有大数据时(大于1M),会出现如下错误: ### Cause: com.mysql.jdbc.PacketTooBigException: Packe ...

  2. [CLR via C#]26. 计算限制的异步操作

    一.CLR线程池基础 前面说过,创建和销毁线程是一个比较昂贵的操作,太多的线程也会浪费内存资源.由于操作系统必须调度可运行的线程并执行上下文切换,所以太多的线程还有损于性能.为了改善这个情况,CLR使 ...

  3. SQL Server密码管理的六个危险判断

    当管理SQL Server内在的帐户和密码时,我们很容易认为这一切都相当的安全.但实际上并非如此.在这里,我们列出了一些对于SQL Server密码来说非常危险的判断. 当管理SQL Server内在 ...

  4. ACCESS作为网站数据库的弊端

    现在网上绝大多数网站都是ACCESS+ASP的形式,因为ACCESS结构简单容易处理,而且也能满足多数的网站程序要求. ACCESS是小型数据库,既然是小型就有他根本的局限性,以下几种情况下数据库基本 ...

  5. java中的代码块执行顺序

    /* 代码块:在Java中,使用{}括起来的代码被称为代码块. 根据其位置和声明的不同,可以分为 局部代码块:局部位置,用于限定变量的生命周期. 构造代码块:在类中的成员位置,用{}括起来的代码.每次 ...

  6. <s:iterator>各种遍历用法

    struts2<S:iterator>遍历map小结 1.MapAction.java import java.util.ArrayList;   import java.util.Has ...

  7. Hibernate框架之注解的配置

    在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式 ...

  8. ASP.NET WebAPI 12 Action的执行

    Action的激活大概可以分为如下两个步骤:Action对应方法的调用,执行结果的协商.在WebAPI中由HttpActionInvoker(System.Web.Http.Controllers)进 ...

  9. weblogic 12c下jxls导出excel报错Could not initialize class org.apache.poi.xssf.usermodel.XSSFVMLDrawing

    周一,开发反馈weblogic 12c下jxls导出excel报错,公司环境和UAT环境均报错,看日志如下: 2016-06-08 09:16:55,825 ERROR org.jxls.util.T ...

  10. Linux守护进程的编程实现(转)

    http://blog.csdn.net/zg_hover/article/details/2553321 http://blog.csdn.net/kongdefei5000/article/det ...