设计模式(二十二)模板方法

一、定义

定义一个操作中算法的框架,而将一些步骤延迟到子类中。模板方法模式使得子类不改变一个算法的结构即可重定义该算法的特定步骤。模板方法是一种类行为型模式

二、描述

模板方法模式结构比较简单,其核心是抽象类和其中的模板方法的设计,包含以下两个角色:
1、AbstractClass(抽象类):在抽象类中定义了一系列基本操作(Primitive Operations),这些基本操作可以是具体的,也可以是抽象的,每一个基本操作对应算法的一个步骤,在其子类中可以重新定义或实现这些步骤。同时,在抽象类中实现了一个模板方法(Template Method),用于定义一个算法的框架。
2、ConcreteClass(具体子类):抽象类的子类,用于实现在父类中声明的抽象基本操作以完成子类特定算法的步骤,也可以覆盖在父类中已经实现的具体基本操作。

三、例子

X公司欲为某银行的业务支撑系统开发一个利息计算模块,利息计算流程如下:
(1)系统根据账号和密码验证用户信息,如果用户信息错误,系统显示错误提示。
(2)如果用户信息正确,则根据用户类型的不同使用不同的利息计算公式计算利息(例如活期账户和定期账户具有不同的利息计算公式)
(3)系统显示利息。

Account:抽象类

C# 复制代码
public abstract class Account
{
    // 基本方法 - 具体方法
    public bool Validate(string account, string password)
    {
        Console.WriteLine("账号 : {0}", account);
        Console.WriteLine("密码 : {0}", password);

        if (account.Equals("张无忌") && password.Equals("123456"))
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    // 基本方法 - 抽象方法
    public abstract void CalculateInterest();

    // 基本方法 - 具体方法
    public void Display()
    {
        Console.WriteLine("显示利息");
    }

    // 基本方法 - 钩子方法
    public virtual bool IsAllowDisplay()
    {
        return true;
    }

    // 模板方法
    public void Handle(string account, string password)
    {
        if (!Validate(account, password))
        {
            Console.WriteLine("账户或密码错误,请重新输入!");
            return;
        }

        CalculateInterest();

        if (IsAllowDisplay())
        {
            Display();
        }
    }
}

CurrentAccount、SavingAccount:活期存款、定期存款,充当具体子类

C# 复制代码
public class CurrentAccount : Account
{
    // 重写父类的抽象基本方法
    public override void CalculateInterest()
    {
        Console.WriteLine("按活期利率计算利息!");
    }

    // 重写父类的钩子方法
    public override bool IsAllowDisplay()
    {
        return base.IsAllowDisplay();
    }
}

public class SavingAccount : Account
{
    // 重写父类的抽象基本方法
    public override void CalculateInterest()
    {
        Console.WriteLine("按定期利率计算利息!");
    }

    // 重写父类的钩子方法
    public override bool IsAllowDisplay()
    {
        return false;
    }
}

Program:测试代码

C# 复制代码
Account account = new CurrentAccount();
if (account != null)
{
    account.Handle("张无忌", "123456");
}
Console.ReadLine();

四、总结

1、优点

(1)在父类中形式化地定义一个算法,而由它的子类来实现细节的处理,在子类实现详细的处理算法时并不会改变算法中步骤的执行次序。
(2)模板方法模式是一种代码复用技术,在类库设计中尤为重要,它提取了类库中的公共行为,将公共行为放在父类中,而通过其子类来实现不同的行为,它鼓励用户恰当地使用继承来实现代码复用。
(3)模板方法模式可实现一种反向控制结构,通过子类覆盖父类的钩子方法来决定某一特定步骤是否需要执行。
(4)在模板方法模式中可以通过子类来覆盖父类的基本方法,不同的子类可以提供基本方法的不同实现,更换和增加新的子类很方便,符合单一职责原则和开闭原则。

2、缺点

(1)模板方法模式需要为每一个基本方法的不同实现提供一个子类,如果父类中可变的基本方法太多,将会导致类的个数增加,系统会更加庞大,设计也会更加抽象,此时,可结合桥接模式来进行设计。

相关推荐
fakerth14 小时前
【OpenHarmony】设计模式模块详解
c++·单例模式·设计模式·openharmony
alibli17 小时前
一文学会设计模式之创建型模式及最佳实现
c++·设计模式
1024肥宅18 小时前
前端常用模式:提升代码质量的四大核心模式
前端·javascript·设计模式
郝学胜-神的一滴1 天前
设计模式依赖于多态特性
java·开发语言·c++·python·程序人生·设计模式·软件工程
帅次1 天前
系统分析师:软件需求工程的软件需求概述、需求获取、需求分析
设计模式·重构·软件工程·团队开发·软件构建·需求分析·规格说明书
EXtreme351 天前
【数据结构】算法艺术:如何用两个栈(LIFO)优雅地模拟队列(FIFO)?
c语言·数据结构·算法·设计模式·栈与队列·摊还分析·算法艺术
1024肥宅2 天前
JavaScript常用设计模式完整指南
前端·javascript·设计模式
特立独行的猫a2 天前
C++观察者模式设计及实现:玩转设计模式的发布-订阅机制
c++·观察者模式·设计模式
better_liang2 天前
每日Java面试场景题知识点之-单例模式
java·单例模式·设计模式·面试·企业级开发
sg_knight2 天前
什么是设计模式?为什么 Python 也需要设计模式
开发语言·python·设计模式