Scott's world.

设计模式-模板方法模式

Word count: 2.1kReading time: 7 min
2019/08/15 Share

设计模式 模板方法模式

模式定义

模板方法模型是一种行为设计模型。模板方法是一个定义在父类别的方法,在模板方法中会呼叫多个定义在父类别的其他方法,而这些方法有可能只是抽象方法并没有实作,模板方法仅决定这些抽象方法的执行顺序,这些抽象方法的实作由子类别负责,并且子类别不允许覆写模板方法。

模式结构


抽象类(AbstractClass): 定义抽象的原语操作(primitive operation) ,具体的子类将重定义它们以实现一个算法, 实现一个模板方法,定义一个算法的骨架。该模板方法不仅调用原语操作,也调用定义
具体子类 (ConcreteClass): 实现原语操作以完成算法中与特定子类相关的步骤。

代码实现

模板方法模式在很多场景都会使用到

比如现在我们假想一个场景,也就是在一个公司,每天进入公司和离开公司都是固定的方法但是工作的实现方法各有不同,我们就把它定义为抽象类方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public abstract class Worker
{
protected String name;

public Worker(String name)
{
this.name = name;
}

public final void workOneDay()
{

System.out.println("-----------------work start ---------------");
enterCompany();
work();
exitCompany();
System.out.println("-----------------work end ---------------");

}

/**
* 工作
*/
public abstract void work();

/**
* 进入公司
*/
public void enterCompany()
{
System.out.println(name + "进入公司");
}

/**
* 离开公司
*/
public void exitCompany()
{
System.out.println(name + "离开公司");
}

}

然后每个工作者都用不同的工作方式来进行各自的工作,我们便用不同的类来实现这个方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class JAVAWorker extends Worker
{

public ITWorker(String name)
{
super(name);
}

@Override
public void work()
{
System.out.println(name + "是JAVA工作者");
}

}


public class GoWorker extends Worker
{

public ITWorker(String name)
{
super(name);
}

@Override
public void work()
{
System.out.println(name + "是Go工作者");
}

}

最后我们的主类也就是分别实现工作者在公司的工作

1
2
3
4
5
6
7
8
9
10
public class Test
{
public static void main(String[] args)
{
Worker a = new JAVAWorker("土豆");
a.workOneDay();
Worker b = new GoWorker("阵雨");
b.workOneDay();
}
}

现在我们已经得到每位工作者在公司的工作流程

最后我们再来设想一下如果今天有人加班,就无法正常离开公司

现在就可以运用到我们的钩子方法,来加以影响超类的逻辑,我们在超类中加以一个判断方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public boolean isOverTime()
{
return false;
}
/**
* 离开公司
*/
public void exitCompany()
{
if (!isOverTime())
{
System.out.println(name + "离开公司");
}else{
System.out.println(name + "因加班无法离开公司");
}

}

然后我们在具体的工作者子类中,加以复写钩子方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class JAVAWorker extends Worker
{

public ITWorker(String name)
{
super(name);
}

@Override
public void work()
{
System.out.println(name + "是JAVA工作者");
}

@Override
public boolean isOverTime()
{
return true;
}


}

然后主类还是不变,我们就可以看到因为钩子方法影响了超类逻辑,所以实现了这一场景

模式分析

我们通过该模式的实现,可以发现我们在生活场景中有很多类似的场景

实现类用来实现细节。抽象类中的模版方法正是通过实现类扩展的方法来完成业务逻辑。只要实现类中的扩展方法通过了单元测试,在模版方法正确的前提下,整体功能一般不会出现大的错误。

模板方法模式的构成比较简单,也就是一个抽象类和一个(或一组)实现类通过继承的结构组成,而其中抽象类的方法分为三种:

  • 抽象方法:父类中只会声明其类而不会去实现,即定义规范,然后交给它的子类去实现
  • 模板方法:由抽象类声明并加以实现.一般来说,模板方法调用抽象方法来完成主要的逻辑功能,而且模板方法大多都会定义为final类型,指明主要的逻辑功能在子类中不能被重写
  • 钩子方法:由抽象类声明并实现.但是子类可以扩展并且可影响模板方法的逻辑

抽象类的任务是搭建逻辑的框架,通常由经验丰富的人员编写,因为抽象类的好坏直接决定了程序是否稳定性。

显而易见,模板方法模式中的声明为abstract的基本操作都是需要迫使子类去实现的,它们仅仅是为模板方法服务的。它们不应该被抽象类(AbstractClass)所公开,所以它们应该protected。

因此模板方法模式中,迫使子类实现的抽象方法应该声明为protected abstract。

模式优缺点

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

  • 缺点

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

模式扩展

  • 模板方法模式与控制反转(好莱坞原则)

    在模板方法模式中,子类不显式调用父类的方法,而是通过覆盖父类的方法来实现某些具体的业务逻辑,父类控制对子类的调用,这种机制被称为好莱坞原则(Hollywood Principle),好莱坞原则的定义为:“不要给我们打电话,我们会给你打电话(Don‘t call us, we’ll call you)”。在好莱坞,把简历递交给演艺公司后就只有回家等待。由演艺公司对整个娱乐项的完全控制,演员只能被动式的接受公司的差使,在需要的环节中,完成自己的演出。模板方法模式充分的体现了“好莱坞”原则。由父类完全控制着子类的逻辑,子类不需要调用父类,而通过父类来调用子类,子类可以实现父类的可变部份,却继承父类的逻辑,不能改变业务逻辑。

  • 模板方法模式符合开闭原则

    模板方法模式意图是由抽象父类控制顶级逻辑,并把基本操作的实现推迟到子类去实现,这是通过继承的手段来达到对象的复用,同时也遵守了开闭原则。

模式总结

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

参考

https://blog.csdn.net/hguisu/article/details/7564039

https://blog.csdn.net/zhengzhb/article/details/7405608

CATALOG
  1. 1. 设计模式 模板方法模式
    1. 1.1. 模式定义
    2. 1.2. 模式结构
    3. 1.3. 代码实现
    4. 1.4. 模式分析
    5. 1.5. 模式优缺点
    6. 1.6. 模式扩展
    7. 1.7. 模式总结
    8. 1.8. 参考