模板方法模式详解

打印 上一主题 下一主题

主题 1035|帖子 1035|积分 3105

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
模板方法模式(Template Method Pattern)是一种运动型设计模式,它在方法中定义算法的框架,延迟到子类中实现。模板方法使得子类可以在不改变算法结构的环境下,重新定义算法中的某些步调。下面对模板方法模式举行详细解说:
一、角色
1.  抽象类(Abstract Class)
•  它定义了一个或多个抽象方法,这些抽象方法由子类实现。抽象类中还定义了一个模板方法,模板方法是一个详细方法,它给出了一个算法的外貌和骨架,并调用抽象方法。
•  例如,在一个文档处理体系中,抽象类可以是DocumentProcessor,它定义了一个抽象方法processContent()用于处理文档内容,还定义了一个模板方法processDocument(),该方法的步调包罗打开文档、处理文档内容、生存文档等,其中处理文档内容的步调调用了processContent()抽象方法。
2.  详细子类(Concrete Subclass)
•  它实现父类的抽象方法,但不改变模板方法所定义的算法结构。详细子类根据现实的业务需求,实现抽象方法中的详细逻辑。
•  继续上面的例子,详细子类可以是TextDocumentProcessor和PDFDocumentProcessor。TextDocumentProcessor实现了processContent()方法,详细逻辑是剖析文本格式的内容;PDFDocumentProcessor也实现了processContent()方法,其逻辑是剖析PDF格式的内容。这两个子类都没有改变processDocument()模板方法所定义的打开、处理、生存的算法结构。
二、优点
1.  封装不变部门,扩展可变部门
•  模板方法模式将不变的算法步调封装在父类的模板方法中,而将可变的步调通过抽象方法延迟到子类实现。这样,子类只必要关注实现可变部门的逻辑,而不必要关心整个算法的流程。例如,在一个电商订单处理体系中,订单处理的流程(如验证订单、处理付出、发货、完成订单等步调)是相对固定的,但不同范例的订单(如普通订单、预售订单、外洋订单等)在处理付出和发货等详细步调上可能有所不同。使用模板方法模式,可以将订单处理的固定流程封装在抽象类的模板方法中,而将不同范例的订单处理付出和发货等可变步调通过抽象方法让子类去实现,从而进步了代码的复用性和可维护性。
2.  运动由父类控制,子类实现
•  父类通过模板方法定义了算法的执行次序和流程控制,子类通过实现抽象方法来提供详细的运动实现。这种模式使得算法的控制逻辑会合在父类中,子类只必要按照父类定义的框架来实现详细的运动,降低了子类之间的耦合度。好比在一个游戏的角色技能开释体系中,技能开释的流程(如技能准备、技能执行、技能结束等)由父类的模板方法控制,而不同角色的详细技能结果(如火球术、冰冻术等)由子类实现,这样可以方便地管理和扩展角色的技能体系。
3.  提取公共代码,便于维护
•  通过将算法的公共部门提取到父类的模板方法中,可以制止代码重复。当必要修改公共部门的逻辑时,只必要在父类中修改模板方法,而不必要在每个子类中都举行修改,从而进步了代码的可维护性。例如,在一个图形绘制体系中,绘制图形的流程(如设置画笔、绘制图形、开释画笔等)有公共部门,使用模板方法模式将这些公共步调放在父类的模板方法中,当必要优化画笔设置的逻辑时,只需修改父类中的相关代码即可。
三、缺点
1.  违反开闭原则
•  如果算法的流程必要改变,那么就必要修改模板方法,这可能会违反开闭原则。因为开闭原则要求软件实体应该对扩展开放,对修改关闭,而修改模板方法意味着要修改父类的代码。例如,在上面的文档处理体系例子中,如果必要在文档处理流程中增长一个校验文档格式的步调,可能就必要修改DocumentProcessor抽象类中的processDocument()模板方法,这就必要修改父类代码。
2.  限制子类的灵活性
•  模板方法定义了算法的固定流程,子类只能在父类定义的框架内举行扩展,这在一定程度上限制了子类的灵活性。如果子类必要举行一些特殊的操作,但父类的模板方法没有提供相应的扩展点,子类可能就无法实现这些特殊操作。好比在订单处理体系中,如果父类的模板方法没有提供在发货前举行特殊包装的扩展点,那么对于一些必要特殊包装的订单(如易碎品订单),子类可能就无法很好地实现这一特殊需求。
四、应用场景
1.  算法步调固定,细节可变场景
•  当一个算法的步调是固定的,但每个步调的详细实现细节可能会根据不同的环境而变革时,得当使用模板方法模式。例如,在一个在线教育平台的课程学习流程中,学习流程(如观看视频、完成考试、提交作业、获取证书等步调)是固定的,但不同范例的课程(如语言类课程、技术类课程等)在完成考试和提交作业等详细步调的实现上可能会有所不同,可以使用模板方法模式来实现。
2.  多子类共用方法,制止代码重复场景
•  当多个子类有共用的方法,并且逻辑雷同,但子类的某些细节必要不同的实现时,可以使用模板方法模式来提取共用的方法到父类中,制止代码重复。好比在一个物流配送体系中,不同范例的货物(如普通货物、生鲜货物、危险品货物等)的配送流程(如接单、配送、签收等步调)有共用的部门,但配送过程中的详细操作(如生鲜货物必要冷藏配送等)有所不同,可以使用模板方法模式来实现。
3.  控制子类扩展场景
•  当必要控制子类的扩展,确保子类不改变算法的整体结构时,模板方法模式是一个很好的选择。例如,在一个软件的权限管理体系中,用户登录的流程(如输入用户名和暗码、验证身份、授权等步调)必要严格控制,不答应子类随意改变,但不同范例的用户(如普通用户、管理员用户等)在授权的详细细节上可能有所不同,可以使用模板方法模式来实现。
五、实现示例(以Java语言为例)
假设我们要实现一个简单的烤咖啡的过程,使用模板方法模式来实现如下:
// 抽象类:咖啡制作抽象类
public abstract class CoffeeMaker {
    // 模板方法,定义了烤咖啡的流程
    public final void makeCoffee() {
        boilWater();
        brew();
        pourInCup();
        addCondiments();
    }
    // 抽象方法,由子类实现详细的冲泡方式
    protected abstract void brew();
    // 抽象方法,由子类实现详细的添加配料方式
    protected abstract void addCondiments();
    // 详细方法,加热水
    private void boilWater() {
        System.out.println("Boiling water");
    }
    // 详细方法,将咖啡倒入杯子
    private void pourInCup() {
        System.out.println("ouring into cup");
    }
}
// 详细子类:制作浓咖啡
public class StrongCoffeeMaker extends CoffeeMaker {
    @Override
    protected void brew() {
        System.out.println("Dripping Strong Coffee through filter");
    }
    @Override
    protected void addCondiments() {
        System.out.println("Adding sugar and milk");
    }
}
// 详细子类:制作卡布奇诺
public class CappuccinoMaker extends CoffeeMaker {
    @Override
    protected void brew() {
        System.out.println("Steaming milk");
    }
    @Override
    protected void addCondiments() {
        System.out.println("Adding steamed milk foam");
    }
}
// 客户端代码
public class TemplateMethodDemo {
    public static void main(String[] args) {
        CoffeeMaker strongCoffeeMaker = new StrongCoffeeMaker();
        strongCoffeeMaker.makeCoffee();
        CoffeeMaker cappuccinoMaker = new CappuccinoMaker();
        cappuccinoMaker.makeCoffee();
    }
}
在这个例子中,CoffeeMaker抽象类定义了一个模板方法makeCoffee(),它给出了烤咖啡的流程,包罗加热水、冲泡、将咖啡倒入杯子、添加配料等步调。其中,冲泡和添加配料的步调是抽象方法,由子类实现详细的逻辑。StrongCoffeeMaker和CappuccinoMaker是详细子类,分别实现了冲泡浓咖啡和制作卡布奇诺的详细逻辑。客户端代码通过创建不同的子类对象来制作不同范例的咖啡,而整个烤咖啡的流程是由父类的模板方法控制的。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

河曲智叟

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表