zoukankan      html  css  js  c++  java
  • 设计模式之模板模式

    定义

      这种类型的设计模式属于行为型模式。它定义一个操作中算法的骨架,而将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构,只是重定义该算法的某些特定步骤。换句话说,模板模式会定义了算法的固定执行逻辑,这个执行逻辑是有父类来控制的,同时将公用的方法逻辑放到父类中维护,而可能改变的方法延迟到子类中实现。

    优缺点

      优点:

    1. 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
    2. 它在父类中提取了公共的部分代码,便于代码复用。
    3. 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。

      缺点:

    1. 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。
    2. 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。

    应用场景

     1.多个子类有相同的逻辑

    2.将公共的行为抽取出来放到一个公共类中,子类通过继承公共类来获取公共方法的使用

    3.多个子类中差异性的内容放到子类里实现

    角色

    抽象方法:在抽象类声明、由其具体子类实现。

    具体方法:在抽象类中声明并实现,在具体子类中可以继承或重写。

    钩子方法:在抽象类中声明并实现(可以是空的实现),子类视情况进行重写覆盖,一般是逻辑判断方法。

    模板方法:定义统一模板算法的方法,提供实现方法,子类一般不需要重写。

    模板模式和策略模式的区别

       模板模式定义了一个统一的算法,子类可以对算法的某一些步骤,进行覆盖重写,可以提高代码的复用率。同过继承的方式实现,依赖比较强,不够灵活。

       策略模式每个子类都是一种实现,可以完全不相同,即便算法之间存在共性,也需要在每个子类重新实现,通过组合的方式实现,可以动态的改变算法,比较灵活。

    代码

    抽象类

    public abstract class Game {
        /**
         * 具体方法
         */
        public void initialize() {
            System.out.println("game initialize .........");
        }
    
        /**
         * 抽象方法
         */
        abstract void startPlay();
    
        abstract void endPlay();
    
        /**
         * 钩子方法
         *
         * @return 是否需要结束
         */
        boolean isNeedEnd() {
            return false;
        }
    
        /**
         * 模板方法
         * final修饰 不允许子类修改
         * 每一个游戏先初始化、开始游戏 是否需要结束游戏 根据钩子进行判断
         */
        public final void play() {
            //初始化游戏
            initialize();
            //开始游戏
            startPlay();
            if (isNeedEnd()) {
                //结束游戏
                endPlay();
            }
        }
    }

    具体类

    /**
     * 具体模板
     * 足球游戏
     */
    public class Football extends Game{
        @Override
        void endPlay() {
            System.out.println("Football Game Finished!");
        }
        @Override
        void startPlay() {
            System.out.println("Football Game Started. Enjoy the game!");
        }
        @Override
        boolean isNeedEnd() {
            return false;
        }
    }

    测试类

    /**
     * 模板测试类
     */
    public class TemplateModeTest {
        public static void main(String[] args) {
            Game game = new Basketball();
            game.play();
            game = new Football();
            game.play();
        }
    }
  • 相关阅读:
    Flask + WSGI + Nginx 环境
    sql字段合并与分组聚合
    杭州优科豪马轮胎有限公司北京经销商
    国家与大洲对应关系json数据
    【C#】编码史记
    【C#】Unicode的流言终结者和编码大揭秘
    【WPF】生成二维码
    【WPF】WriteableBitmap和BitmapImage的相互转换
    TPL之延续任务
    【C#】日期格式转换
  • 原文地址:https://www.cnblogs.com/htyj/p/13741331.html
Copyright © 2011-2022 走看看