快速学习设计模式-模板方法模式

我对设计模式的理解:

多数开发人员应该知道设计模式这个东西;部分人知道23种设计模式;少数人能够熟练使用设计模式,极少数人精通设计模式。

其实23种设模式,其实只是入门,这就相当于你学英语,学会了26个英文字母,才能开始学习单词。同样23种设计模式,只是字母表,想要到精通的层次,要能够灵活的使用设计模式,灵活的组合设计模式。

设计模式是我短期计划中的一部分,我的文章致力于最快最简单的掌握每一个设计模式。

我的设计模式相关的文章,都会在开篇使用一句话,来描述一个设计模式!

该模式设计关键点

使用抽象类,定义算法骨架,然后子类根据不同的场景来实现算法细节,达到解决不同问题的目的。

 

最大的好处

代码复用,代码结构清晰,符合开闭原则。

 

最大的缺点

类的个数膨胀。

 

UML图

 该设计模式非常的简单,很容易掌握,也比较容易用到。

 定义一个抽象类(红色框),算法骨架方法,跟业务挂钩的抽象方法;

 然后由实现类,去实现跟自己业务相关的方法。

 

简单的使用

(一般大家对游戏比较有共鸣,那就举一个游戏的栗子吧):

 首先我定义了一个抽象类:AbstractGame

 该抽象类有五个方法,其中两个两个用final修饰的方法,其中一个是算法骨架,openGame(),该方法里边定义好了算法的执行流程,必须按照我预期的进行加载。我不想让子类擅自修改我们的算法骨架,所以我用final来修饰

 另外三个方法是抽象方法,分别是加载场景,和加载背景音乐的,和连接用户的方法。

abstract class AbstractGame {
    /**
     * 游戏算法骨架
     */
    final void openGameTempl(){
        //加载游戏场景
        loadScene();
        //加载背景音乐
        loadBackgroundMusice();
        //连线游戏用户
        connectedUsers();
        //开始游戏
        begin();
       
    }

    /**
     * 加载游戏场景
     */
    abstract void loadScene();

    /**
     * 加载背景音乐
     */
    abstract void loadBackgroundMusice();
    /**
     * 连线游戏用户
     */
    abstract connectedUsers();
    /**
     * 开始游戏
     */ 
    final void begin(){
         System.out.println("欢迎来到召唤师峡谷");
    }


}

 

 接着是实现类,三个方法是抽象方法,分别是加载场景,和加载背景音乐的,和连接用户的方法。如果想加载不同的游戏地图进来,则可以用子类去继承我们的抽象方法。如果想要是使用不同的连接用户的方法,使用语音,使用第三方聊天工具。

同样道理,如果是3v3 的游戏,则再定义一个子类来实现AbstractGame。 游戏的加载顺序是不变的,唯一边的就是我们的抽象方法。


class GameV5 extends AbstractGame{

    /**
     * 加载游戏场景
     */
    @Override
    void loadScene(){
        System.out.println("加载5v5的游戏地图");
    }

    /**
     * 加载背景音乐
     */
    @Override
    void loadBackgroundMusice(){
        System.out.println("加载大乱斗的背景音乐");
    }

    /**
     * 连线游戏用户
     */
    @Override
    void connectedUsers(){
        System.out.println("使用QT语音进行用户的连接");
    }


}

 

 

 想要开始一场5V5的游戏,则直接new一个对象即可。 

public class DoGame {
    public static void main(String[] args) {
        GameV5 gameV5 = new GameV5();
        gameV5.openGameTempl();
        
    }
}

 

 

灵活运用-模板方法下的钩子程序

其实这个是非常灵活的,还可以定义下边的四个方法为抽象方法。唯独定义全部的方法为抽象方法,不太合适。留出一个方法来定义算法骨架,这是模板方法的一个精髓点。

同事,我们还可以不把抽象类写太死,预留出来一些权利给子类。也就是通常说的钩子程序。

下边我对上边的案例做一点改变

abstract class AbstractGame {
    /**
     * 游戏算法骨架
     */
    final void openGameTempl(){
        //加载游戏场景
        loadScene();
        //加载背景音乐
        loadBackgroundMusice();
        //连线游戏用户
        connectedUsers();
        //开始游戏
        begin();
       
    }

    /**
     * 加载游戏场景
     */
    abstract void loadScene();

    /**
     * 加载背景音乐
     */
    abstract void loadBackgroundMusice();

    /**
     * 预留一个钩子,由子类决定是否加载
     */
    if(isLoadSkin()){
     //加载皮肤
      loadSkin();
    }

    /*
     * 是非加载皮肤
     */  
    protected boolean isLoadSkin(){
       return false;
    }

    /**
     * 连线游戏用户
     */
    abstract connectedUsers();

    /**
     * 开始游戏
     */ 
    final void begin(){
         System.out.println("欢迎来到召唤师峡谷");
    }


}

 

  在实现类中决定,是否加载皮肤。


class GameV5 extends AbstractGame{

    /**
     * 加载游戏场景
     */
    @Override
    void loadScene(){
        System.out.println("加载5v5的游戏地图");
    }

    /**
     * 加载背景音乐
     */
    @Override
    void loadBackgroundMusice(){
        System.out.println("加载大乱斗的背景音乐");
    }

    /**
     * 连线游戏用户
     */
    @Override
    void connectedUsers(){
        System.out.println("使用QT语音进行用户的连接");
    }
    
     /*
     * 是非加载皮肤
     */ 
    @Override 
    protected boolean isLoadSkin(){
       return true;
    }


}

 

 

 想要开始一场5V5的游戏,则直接new一个对象即可。 

public class DoGame {
    public static void main(String[] args) {
        GameV5 gameV5 = new GameV5();
        gameV5.openGameTempl();
        
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值