模板方法模式

摘自《大话设计模式》(程杰 著)

既然用了继承,并且肯定这个继承有意义,就应该要成为子类的模板,所有重复的代码都应该要上升到父类去,而不是让每个子类都去重复。
当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。

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

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

image

代码

AbstractClass.cs 抽象类

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

abstract class AbstractClass
{
    // 一些抽象行为,放到子类去实现
    public abstract void PrimitiveOperation1();
    public abstract void PrimitiveOperation2();

    // 模板方法,给出了逻辑的骨架
    // 逻辑的组成是一些相应的抽象操作,它们都推迟到子类实现
    public void TemplateMethod()
    {
        PrimitiveOperation1();
        PrimitiveOperation2();
        Console.WriteLine("");
    }
}

ConcreteClass.cs 具体类

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

class ConcreteClassA : AbstractClass
{
    public override void PrimitiveOperation1()
    {
        Console.WriteLine("具体类A方法1实现");
    }
    public override void PrimitiveOperation2()
    {
        Console.WriteLine("具体类A方法2实现");
    }
}

class ConcreteClassB : AbstractClass
{
    public override void PrimitiveOperation1()
    {
        Console.WriteLine("具体类B方法1实现");
    }
    public override void PrimitiveOperation2()
    {
        Console.WriteLine("具体类B方法2实现");
    }
}

Program.cs

AbstractClass c;

c = new ConcreteClassA();
c.TemplateMethod();

c = new ConcreteClassB();
c.TemplateMethod();

Console.Read();

示例

image

TestPaper.cs

abstract class TestPaper
{
    public void TestQuestion1()
    {
        Console.WriteLine("杨过得到,后来给了郭靖,炼成倚天剑、屠龙刀的玄铁可能是 [] a.球磨铸铁 b.马口铁 c.高速合金钢 d.碳素纤维");
        Console.WriteLine("答案: " + Answer1());
    }

    public void TestQuestion2()
    {
        Console.WriteLine("杨过、程英、陆无双铲除了情花,造成[] a.使这种植物不再害人b.使一种珍稀物种灭绝c.破坏了那个生物圈的生态平衡d.造成该地区沙漠化");
        Console.WriteLine("答案: " + Answer2());
    }

    public void TestQuestion3()
    {
        Console.WriteLine("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] a.阿司匹林 b.牛黄解毒片 c.氟哌酸 d.让他们喝大量的生牛奶 e.以上全不对");
        Console.WriteLine("答案: " + Answer3());
    }

    protected virtual string Answer1()
    {
        return "";
    }
    protected virtual string Answer2()
    {
        return "";
    }

    protected virtual string Answer3()
    {
        return "";
    }
}

TestPaperA.cs

//学生甲抄的试卷
class TestPaperA : TestPaper
{
    public new void TestQuestion1()
    {
        base.TestQuestion1();
        Console.WriteLine("答案: b");
    }

    public new void TestQuestion2()
    {
        base.TestQuestion2();
        Console.WriteLine("答案:b");
    }

    public new void TestQuestion3()
    {
        base.TestQuestion3();
        Console.WriteLine("答案:b");
    }
}

TestPaperB.cs 和 TestPaperA.cs类似

Program.cs 客户端

Console.WriteLine("同学甲抄的试卷:");

TestPaperA studentA = new TestPaperA();

studentA.TestQuestion1();
studentA.TestQuestion2();
studentA.TestQuestion3();

Console.WriteLine("同学乙抄的试卷:");

TestPaperB studentB = new TestPaperB();

studentB.TestQuestion1();
studentB.TestQuestion2();
studentB.TestQuestion3();

Console.Read();
posted @ 2025-12-18 09:30  苦涩如影相随固  阅读(27)  评论(0)    收藏  举报