设计模式使用场景实现示例及优缺点(行为型模式——模板方法模式)

07-17 1276阅读

模板方法模式(Template Method Pattern)

模板方法模式(Template Method Pattern)是一种行为设计模式,它定义了一个操作中的算法的骨架,将算法的一些步骤延迟到子类中。这样可以在不改变算法的结构的前提下,重新定义算法的某些特定步骤。

设计模式使用场景实现示例及优缺点(行为型模式——模板方法模式)
(图片来源网络,侵删)

核心组件

  • AbstractClass(抽象类):这是一个抽象基类,它定义了一套算法的模板。它实现了模板方法,定义了算法的骨架,具体步骤由子类实现。
  • ConcreteClass(具体类):这些类继承自抽象基类,并实现其算法中的具体步骤。

    适用场景

    1. 一次性实现算法的不变部分:
      • 当算法的大部分结构固定不变,但某些步骤具有多变性时,可使用模板方法模式。
      • 各子类中公共行为应提取到单一位置避免代码重复:
        • 通过模板方法模式,可以将公共行为提取到超类中,通过继承机制复用这部分代码。
        • 控制子类扩展:
          • 模板方法模式通过将算法的核心流程固化在超类中,防止子类破坏原有算法的结构。

    实现实例

    以一个简单的游戏开发为例,其中游戏的基本结构(启动、开始、结束)是固定的,但具体每个阶段的实现可以根据不同类型的游戏变化。使用模板方法模式可以固定游戏的主体流程,而将具体步骤的实现留给子类:

    抽象类(Abstract Class)

    这个类定义了游戏的基本流程,并将具体实现留给子类。

    public abstract class Game {
        abstract void initialize();
        abstract void startPlay();
        abstract void endPlay();
        // 模板方法
        public final void play() {
            initialize();  // 初始化游戏
            startPlay();   // 开始游戏
            endPlay();     // 结束游戏
        }
    }
    
    具体类(Concrete Classes)

    这些类继承自抽象基类,并实现了其具体的操作。

    public class Cricket extends Game {
        @Override
        void initialize() {
            System.out.println("Cricket Game Initialized! Start playing.");
        }
        @Override
        void startPlay() {
            System.out.println("Cricket Game Started. Enjoy the game!");
        }
        @Override
        void endPlay() {
            System.out.println("Cricket Game Finished!");
        }
    }
    public class Football extends Game {
        @Override
        void initialize() {
            System.out.println("Football Game Initialized! Start playing.");
        }
        @Override
        void startPlay() {
            System.out.println("Football Game Started. Enjoy the game!");
        }
        @Override
        void endPlay() {
            System.out.println("Football Game Finished!");
        }
    }
    
    客户端代码(Client Code)

    这部分代码演示了如何使用模板方法模式来规范游戏的流程。

    public class Client {
        public static void main(String[] args) {
            Game game = new Cricket();
            game.play();  // 按照Cricket的流程执行游戏
            game = new Football();
            game.play();  // 按照Football的流程执行游戏
        }
    }
    

    优缺点

    优点
    1. 提高代码复用性:
      • 将通用部分的代码放在抽象的父类中,减少了子类的重复代码。
      • 扩展性好:
        • 新增具体类时,只需实现算法的可变部分,不需修改已有的代码。
        • 控制子类扩展:
          • 可以在超类中定义严格的算法规则,限定子类的行为和结构。
    缺点
    1. 对继承的依赖:
      • 模板方法模式通过继承来实现,可能会导致过多的类层次。
      • 可能违背Liskov替换原则:
        • 如果子类不适当地实现父类的方法,可能会违背Liskov替换原则。

    类图

    +----------------+         +------------------+
    |   AbstractClass|-------->|   ConcreteClass  |
    +----------------+         +------------------+
    | + templateMethod()       | + step1()        |
    | + step1()                | + step2()        |
    | + step2()                +------------------+
    | + step3()                |
    +----------------+         |
    | + step3()                |
    +----------------+         |
                               |
          +-------------------+|
          |                   |
    +---------------+ +-----------------+
    |ConcreteClassA | |ConcreteClassB   |
    +---------------+ +-----------------+
    | + step1()     | | + step1()       |
    | + step2()     | | + step2()       |
    | + step3()     | | + step3()       |
    +---------------+ +-----------------+
    

    注意事项

    设计灵活性与复杂性:

    模板方法模式虽然提高了代码的复用性,但也可能导致设计过于复杂。在设计时应确保不过度使用,以免造成系统的不必要复杂。

    子类的设计约束:

    子类实现时必须遵循抽象基类的方法模板,这限制了子类的灵活性。设计者需要在提供足够的灵活性和维持算法结构之间找到平衡。

    重构与维护:

    如果模板方法本身需要修改,可能会影响到所有的子类。因此,在模板方法中应尽量减少修改的可能性,确保长时间的稳定性。

    总结

    模板方法模式是一种强大的设计工具,通过预定义算法的结构,提供了高度的复用性和扩展性。它不仅适用于软件开发,还广泛应用于系统设计和业务流程管理。通过对模式的适当扩展和优化,可以有效应对更加复杂和动态的设计挑战。这种模式的成功实施需要深入理解业务需求和技术上的灵活运用,以确保设计的可维护性和系统的可扩展性。

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]