软件设计模式——模版方法模式(Template Pattern)

定义

在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使的子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。将主要的方法定义为final,防止子类修改算法骨架,将子类必须实现的方法定义为abstract。而普通的方法(无final或abstract修饰)则称之为钩子。

钩子作用

1)作为可选内容,子类可以重写或者置之不理
2)让子类有机会对模板方法中即将发生的或者已经发生的步骤做出反应
3)作为控制条件,使得子类可以影响到抽象类中的算法流程
角色:模板抽象父类,模板子类

优点

1)模板方法模式在一个类中形式化地定义算法,而由它的子类实现细节的处理。
2)模板方法是一种代码复用的基本技术。它们在类库中尤为重要,它们提取了类库中的公共行为。
3)模板方法模式导致一种反向的控制结构,这种结构有时被称为“好莱坞法则” ,即“别找我们,,我们找你”通过一个父类调用其子类的操作(而不是相反的子类调用父类),通过对子类的扩展增加新的行为,符合“开闭原则”

缺点

每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象,但是更加符合“单一职责原则”,使得类的内聚性得以提高。

总结

1)模板方法模式是一种类的行为型模式,在它的结构图中只有类之间的继承关系,没有对象关联关系。
2)板方法模式是基于继承的代码复用基本技术,模板方法模式的结构和用法也是面向对象设计的核心之一。在模板方法模式中,可以将相同的代码放在父类中,而将不同的方法实现放在不同的子类中。
3)在模板方法模式中,我们需要准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来让子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现,这就是模板方法模式的用意。模板方法模式体现了面向对象的诸多重要思想,是一种使用频率较高的模式。

实现

我们将创建一个Game的抽象类,Cricket和Football子类去实现它。
这里写图片描述

//Create an abstract class with a template method being final
public abstract class Game {
    abstract void initialize();
    abstract void startPlay();
    abstract void endPlay();

    //template method
    public final void play()
    {
        //initialize the game
        initialize();

        //start game
        startPlay();

        //end game
        endPlay();
    }
}
//create concrete classes extending the above class
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!");
    }

}
//Use the Game's template method play() to demonstrate a defined way of playing game.
public class TemplatePatternDemo {
    public static void main(String[] args) {
        Game game = new Cricket();
        game.play();
        System.out.println();
        game = new Football();
        game.play();
    }
}

Verify the output

Cricket Game Initialized!Start Playing
Cricket Game Started. Enjoy the game!
Cricket Game finished!

Football Game Initialized! Start playing.
Football Game Started. Enjoy the game!
Football Game Finished!

下面再举另外一个例子:获取一段程序运行的时间

abstract class GetTime
{
    public final void getTime()
    {
        //确定的功能
        long start = System.currentTimeMillis();

        //不确定的功能
        runcode();

        //确定的功能
        long end = System.currentTimeMillis();
        //确定的功能
        System.out.println("毫秒:"+(end-start));
    }
    //不确定的功能暴露出去,让子类实现,不一定是抽象的。
    public abstract void runcode();
}
class subTime extends GetTime
{
        public void runcode()
        {
                for(int i = 0;i<4000;i++)
                {
                    System.out.print(i);    
                }   
        }   
}
class TemplateDemo
{
    public static void main(String[] args)
    {
            subTime st = new subTime();
            //GetTime gt = new GetTime();
            st.getTime();   
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值