宏观导图
细节展示
1、结构图
2、关键代码
<span style="font-family:KaiTi_GB2312;font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TemplateMethod_Pattern
{
class Program
{
static void Main(string[] args)
{
AbstracClass c;
c = new ConcreteClasssA();
c.TemplateMethod();
c = new ConcreteClassB();
c.TemplateMethod();
Console.Read();
}
}
//定义一个抽象类,注意此处不能为接口。因为里面可能有具体的方法实现
abstract class AbstracClass
{
public abstract void PrimitiveOperation1();
public abstract void PrimitiveOperation2();
public virtual bool PrimitiveOperation3() // 定义一个钩子方法
{
return true;
}
public void TemplateMethod() // 定义一个模板方法,确定算法的骨架。算法的执行顺序
{
PrimitiveOperation1();
PrimitiveOperation2();
if (PrimitiveOperation3()) //如果钩子方法PrimitiveOperation3的返回值为true ,则执行输出
{
Console.WriteLine("成功实现对父类的反向控制!");
}
}
}
//具体策略类,继承抽象类。实现抽象方法,利用钩子函数对父类实现反向控制
class ConcreteClasssA : AbstracClass
{
public override void PrimitiveOperation1()
{
Console.WriteLine("具体策略A的1实现");
}
public override void PrimitiveOperation2()
{
Console.WriteLine("具体策略A的2实现");
}
public override bool PrimitiveOperation3()
{
//return true; //执行父类的钩子方法PrimitiveOperation3
return false; //不执行父类中的钩子方法PrimitiveOperation3
}
}
class ConcreteClassB : AbstracClass
{
public override void PrimitiveOperation1()
{
Console.WriteLine("具体策略b的1实现");
}
public override void PrimitiveOperation2()
{
Console.WriteLine("具体策略b的2实现");
}
public override bool PrimitiveOperation3()
{
//return true; //执行父类的钩子方法PrimitiveOperation3
return false; //不执行父类中的钩子方法PrimitiveOperation3
}
}
}
</span>
3、基本概念理解
3.1模板方法:定义在抽象类中的、把基本操作方法组合在一起形成一个总算法或一个总行为的方法。这个模板方法定义在抽象类中,并由子类不加以修改地完全继承下来。模板方法是一个具体方法,它给出了一个顶层逻辑框架,而逻辑的组成步骤在抽象类中可以是具体方法,也可以是抽象方法。由于模板方法是具体方法,因此模板方法模式中的抽象层只能是抽象类,而不是接口。
3.2基本方法:实现算法各个步骤的方法,是模板方法的组成部分。它分为三种,分别是:钩子方法,抽象方法,具体方法。
3.21钩子方法:由一个抽象类或具体类声明并实现,而其子类可能会加以扩展。通常在父类中给出的实现是一个空实现(可使用virtual关键字将其定义为虚函数),并以该空实现作为方法的默认实现,当然钩子方法也可以提供一个非空的默认实现。钩子方法分两种,第一种:与具体的步骤挂钩,实现子类对父类的反向控制。第二种是:写一个具体实现为空的钩子函数。怎么样,是不是有点晕?其实,钩子的意义很简单。就像我们平常在窗口要一份麻辣烫面,虽然制作麻辣烫面的过程是稳定的,可以看做是一个模板。但是,通常我们可以自主选择是否需要放辣椒、麻油、醋、香菜、葱花等辅料。这个过程就需要我们用到钩子函数了!让它来决定是否执行这些符合个性化的算法步骤。
3.22抽象方法:由抽象类声明,具体实现交给子类。
3.33具体方法:由抽象类、具体类声明并实现,其子类可完全继承也可以进行覆盖。
4、对比
抽象方法VS钩子方法
两者的不同之处:
一个字:“子类如果没有覆盖父类中定义的钩子方法,编译可正常通过,如果没有覆盖父类中声明的抽象方法,编译将报错。”
小结:
里面很多的东西都是初次接触,但是都来自生活。其实是老熟人了。比如:钩子、现实生活中就有钩子啊!让两样东西挂钩,进行关联,一个意思嘛!有什么难的?
PS:好莱坞原则是说“你永远不要联系我,如果有需要我会联系你!”