大话设计模式:第10章 模板方法模式

第10章:模板方法模式

重复 = 易错 + 难改

模板方法模式

既然用了继承,并且肯定这个继承有意义,就应该要成为子类的模板,所有重复的代码都应该要上升到父类去,而不是让每个子类都去重复。

当要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,通常考虑用模板方法模式来处理。

模板(template)方法模式:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某终特定步骤。

在这里插入图片描述

AbstractClass:抽象类、抽象模板,定义并实现了一个模版方法。这个模版方法一般是一个具体方法,给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也可能调用一些具体方法。

在这里插入图片描述

ConcreteClass:实现父类所定义的一个或多个抽象方法。每一个AbstractClass都可以有任意多个ConcreteClass之对应,而每一个ConcreteClass都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。

在这里插入图片描述
客户端调用

在这里插入图片描述

模板方法模式示例

任务:抄写题目并作答

在这里插入图片描述

from abc import ABC, abstractmethod
from typing import Text
# 金庸小说考题试卷

class TestPaper(ABC):
    
    def __init__(self) -> None:
        pass
    
    def test_question_1(self) -> None:
        print(
            "杨过得到,后来给郭靖,炼成倚大剑、屠龙刀的玄铁可能是【】:",
            "a. 球磨铸铁;b. 马口铁;c. 高速合金钢;d. 碳素纤维"
        )
        print("答案:", self._answer_1())
        
    def test_question_2(self) -> None:
        print(
            "杨过、程英、陆无双铲除了情花,造成【】:",
            "a. 使这种植物不再害人;b. 使一种珍稀物种灭绝;c. 破坏了那个生物圈的生态平衡;d. 造成该地区沙漠化"
        )
        print("答案:", self._answer_2())
        
    def test_question_3(self) -> None:
        print(
            "蓝凤凰致使华山师徒、桃吞六仙呕吐不止,如果你是大夫,会给他们开什么药【】:",
            "a.阿司匹林;b. 牛黄解毒片;c. 氟哌酸;d. 让他们喝大量的生牛奶;e. 以上全不对"
        )
        print("答案:", self._answer_3())
        
    @abstractmethod
    def _answer_1(self) -> Text:
        pass
    
    @abstractmethod
    def _answer_2(self) -> Text:
        pass
    
    @abstractmethod
    def _answer_2(self) -> Text:
        pass
        
# 学生甲抄的试卷

class TestPaperA(TestPaper):
    
    def _answer_1(self):
        return "b"
    def _answer_2(self):
        return "c"
    def _answer_3(self):
        return "a"
    
    
# 学生乙抄的试卷

class TestPaperB(TestPaper):
    
    def _answer_1(self):
        return "c"
    def _answer_2(self):
        return "a"
    def _answer_3(self):
        return "a"
    
# 客户端代码

if __name__ == "__main__":
    
    print("学生甲抄的试卷")
    student_a = TestPaperA()
    student_a.test_question_1()
    student_a.test_question_2()
    student_a.test_question_3()
    
    print("学生乙抄的试卷")
    student_b = TestPaperB()
    student_b.test_question_1()
    student_b.test_question_2()
    student_b.test_question_3()

学生甲抄的试卷
杨过得到,后来给郭靖,炼成倚大剑、屠龙刀的玄铁可能是【】: a. 球磨铸铁;b. 马口铁;c. 高速合金钢;d. 碳素纤维
答案: b
杨过、程英、陆无双铲除了情花,造成【】: a. 使这种植物不再害人;b. 使一种珍稀物种灭绝;c. 破坏了那个生物圈的生态平衡;d. 造成该地区沙漠化
答案: c
蓝凤凰致使华山师徒、桃吞六仙呕吐不止,如果你是大夫,会给他们开什么药【】: a.阿司匹林;b. 牛黄解毒片;c. 氟哌酸;d. 让他们喝大量的生牛奶;e. 以上全不对
答案: a
学生乙抄的试卷
杨过得到,后来给郭靖,炼成倚大剑、屠龙刀的玄铁可能是【】: a. 球磨铸铁;b. 马口铁;c. 高速合金钢;d. 碳素纤维
答案: c
杨过、程英、陆无双铲除了情花,造成【】: a. 使这种植物不再害人;b. 使一种珍稀物种灭绝;c. 破坏了那个生物圈的生态平衡;d. 造成该地区沙漠化
答案: a
蓝凤凰致使华山师徒、桃吞六仙呕吐不止,如果你是大夫,会给他们开什么药【】: a.阿司匹林;b. 牛黄解毒片;c. 氟哌酸;d. 让他们喝大量的生牛奶;e. 以上全不对
答案: a

模板方法模式特点

模板方法模式提供了一个代码复用平台,把不变行为搬移到超类,并去除子类中的重复代码。

当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现。通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。

猜你喜欢

转载自blog.csdn.net/zhaoyin214/article/details/105797393