设计模式之-模板方法模式
定义:
模板方法模式(TemplateMethod Pattern) :定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板该当使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
模板方法模式参与者
- AbstractClass:实现了一个模板方法,定义了算法的骨架,具体子类将重定义特定的方法以实现一个算法的步骤。
- ConcreteClass:实现AbstractClass类中特定的方法以完成算法中与特定子类相关的步骤。
模板方法模式基本代码
AbstractClass类:
namespace TemplateMethodPattern.BasicStructure { abstract class AbstractClass { public abstract void PrimitiveOperation1(); public abstract void PrimitiveOperation2(); /// <summary> /// 模板方法 /// 给出了逻辑的骨架,而逻辑的组成是一些相应的抽象操作 /// 这些逻辑都推迟到子类实现 /// </summary> public void TemplateMethod() { PrimitiveOperation1(); PrimitiveOperation2(); Console.WriteLine(""); } } }
ConcreteClassA类:
namespace TemplateMethodPattern.BasicStructure { class ConcreteClassA : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具体类A方法1实现"); } public override void PrimitiveOperation2() { Console.WriteLine("具体类A方法2实现"); } } }
ConcreteClassB类:
namespace TemplateMethodPattern.BasicStructure { class ConcreteClassB : AbstractClass { public override void PrimitiveOperation1() { Console.WriteLine("具体类B方法1实现"); } public override void PrimitiveOperation2() { Console.WriteLine("具体类B方法2实现"); } } }
客户端调用代码:
static void Main(string[] args) { try { {//BasicStructure AbstractClass c = new ConcreteClassA(); c.TemplateMethod(); c = new ConcreteClassB(); c.TemplateMethod(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); }
结果如下:
用模板方法模式实现iphone手机的组装
场景模拟:根据各部件来组装一部iphone手机,一部手机除了内存不同外,其它的组装步骤都一样。
AppleHandset(苹果手机)类——AbstractClass类
namespace TemplateMethodPattern.SituationSimulation { abstract class AppleHandset { /// <summary> /// 手机基架 /// </summary> public void Frame() { Console.WriteLine("手机基架"); } /// <summary> /// 手机摄像头 /// </summary> public void Camera() { Console.WriteLine("安装手机基架"); } /// <summary> /// 手机摄像头 /// </summary> public void Battery() { Console.WriteLine("安装手机电池"); } /// <summary> /// 手机内存卡 /// </summary> public abstract void MemoryCard(); /// <summary> /// 组装手机 /// </summary> public void Assemble() { Frame(); Camera(); Battery(); MemoryCard(); Console.WriteLine(""); } } }
AppleHandset64G(64G苹果手机)类——ConcreteClassA类
namespace TemplateMethodPattern.SituationSimulation { class AppleHandset64G : AppleHandset { public override void MemoryCard() { Console.WriteLine("插上64G内存卡"); } } }
AppleHandset128G(128G苹果手机)类——ConcreteClassB类
namespace TemplateMethodPattern.SituationSimulation { class AppleHandset128G : AppleHandset { public override void MemoryCard() { Console.WriteLine("插上128G内存卡"); } } }
客户端调用代码:
static void Main(string[] args) { try { {//SituationSimulation AppleHandset appleHandset = new AppleHandset64G(); appleHandset.Assemble(); appleHandset = new AppleHandset128G(); appleHandset.Assemble(); } } catch (Exception ex) { Console.WriteLine(ex.Message); } Console.ReadKey(); }
结果如下:
优点:
模板方法模式的优点
- 实现了代码的利用。
- 能够灵活应对子步骤的变化,符合开放-封闭原则
缺点:
模板方法模式的缺点
- 因为引入了一个抽象类,如果具体实现过多的话,需要用户或开发人员需要花更多的时间去理清类之间的关系。
适用环境:
根据模板方法模式的使用目的,常见的模板方法模式有以下几种类型:
- 一次性实现一个算法的不变部分,并将可变的行为留给子类来实现。
- 各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。
- 控制子类扩展。模板方法只允许在特定点进行扩展,而模板部分则是稳定的。
总结:
- TemplateMethod模式是一种非常基础性的设计模式,在面向对象系统中大量应用。它用最简洁的机制(基础、多态)为很多应用程序框架提供了灵活的扩展点,是代码复用方面的基本实现结构。
- 在具体实现方面,被TemplateMethod调用的虚方法可以具有实现,也可以没有任何实现(抽象方法或虚方法)。但一般推荐将它们设置为protected方法使得只有子类可以访问它们。
- 模板方法模式通过对子类的扩展增加新的行为,符合“开闭原则”。