A、B两学生进行考试,试题由自己从黑板上抄下来进行考试,我们来实现这样一个考试的程序。
1、TestPaperA代表学生A的试卷
<span style="font-size:18px;">public class TestPaperA
{
public void testQuestion1()
{
System.out.println("杨过最喜欢谁?a、小龙女 b、郭靖 c、郭芙 d、郭襄");
System.out.println("答案:a");
}
public void testQuestion2()
{
System.out.println("杨过的手被谁砍断的?a、小龙女 b、李莫愁 c、郭芙 d、黄蓉");
System.out.println("答案:b");
}
}</span>
2、TestPaperB代表学生B的试卷
<span style="font-size:18px;">public class TestPaperB
{
public void testQuestion1()
{
System.out.println("杨过最喜欢谁?a、小龙女 b、郭靖 c、郭芙 d、郭襄");
System.out.println("答案:d");
}
public void testQuestion2()
{
System.out.println("杨过的手被谁砍断的?a、小龙女 b、李莫愁 c、郭芙 d、黄蓉");
System.out.println("答案:c");
}
}</span>
3、客户端的测试类Client,分别显示出AB的试卷
<span style="font-size:18px;">public class Client
{
public static void main(String[] args)
{
System.out.println("A抄的试卷:");
TestPaperA studentA=new TestPaperA();
studentA.testQuestion1();
studentA.testQuestion2();
System.out.println("B抄的试卷:");
TestPaperB studentB=new TestPaperB();
studentB.testQuestion1();
studentB.testQuestion2();
}
}
</span>
分析上面的代码我们可以发现TestPaperA和TestPaperB中的代码非常的重复,不同的地方只有选项不同而已。这样我们就考虑抽象出一个父类,让TestPaperA和TestPaperB继承这个父类,它们中只要修改选项答案就可以了。
代码修改如下:
1、抽象出来的父类TestPaper
public class TestPaper
{
public void testQuestion1()
{
System.out.println("杨过最喜欢谁?a、小龙女 b、郭靖 c、郭芙 d、郭襄");
System.out.println("答案:"+Answer1());
}
public String Answer1()
{
return "";
}
public void testQuestion2()
{
System.out.println("杨过的手被谁砍断的?a、小龙女 b、李莫愁 c、郭芙 d、黄蓉");
System.out.println("答案:"+Answer2());
}
public String Answer2()
{
return "";
}
}
2、让TestPaperA继承父类TestPaper,并重写Answer方法
public class TestPaperA extends TestPaper
{
@Override
public String Answer1()
{
// TODO Auto-generated method stub
return "a";
}
@Override
public String Answer2()
{
// TODO Auto-generated method stub
return "b";
}
}
3、TestPaperB如上
public class TestPaperB extends TestPaper
{
@Override
public String Answer1()
{
// TODO Auto-generated method stub
return "b";
}
@Override
public String Answer2()
{
// TODO Auto-generated method stub
return "c";
}
}
4、客户端测试类
public class Client
{
public static void main(String[] args)
{
System.out.println("A抄的试卷:");
TestPaper studentA=new TestPaperA();
studentA.testQuestion1();
studentA.testQuestion2();
System.out.println("B抄的试卷:");
TestPaper studentB=new TestPaperB();
studentB.testQuestion1();
studentB.testQuestion2();
}
}
我们可以看到更改后的代码简洁,避免了冗余。TestPaper就是一个模板,在模板的基础上在稍加修改就可以完成TestPaperA和TestPaperB实现的功能。
当我们要完成在某一个细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定的步骤。
模板方法模式的示例代码如下:
1、AbstractClass类,一个抽象模板
public abstract class AbstractClass
{
public abstract void primitiveOperation1();
public abstract void primitiveOperation2();
public void templateMethod()
{
primitiveOperation1();
primitiveOperation2();
System.out.println("抽象模板方法");
}
}
2、ConcreteClassA类,实现父类的一个或多个抽象方法
public class ConcreteClassA extends AbstractClass
{
@Override
public void primitiveOperation1()
{
// TODO Auto-generated method stub
System.out.println("具体类A实现方法1");
}
@Override
public void primitiveOperation2()
{
// TODO Auto-generated method stub
System.out.println("具体类A实现方法2");
}
}
3、
ConcreteClassB类,实现父类的一个或多个抽象方法
public class ConcreteClassB extends AbstractClass
{
@Override
public void primitiveOperation1()
{
// TODO Auto-generated method stub
System.out.println("具体类B实现方法1");
}
@Override
public void primitiveOperation2()
{
// TODO Auto-generated method stub
System.out.println("具体类B实现方法2");
}
}
4、客户端代码
public class Client
{
public static void main(String[] args)
{
AbstractClass a;
a=new ConcreteClassA();
a.templateMethod();
a=new ConcreteClassB();
a.templateMethod();
}
}
当不变和可变的行为在子类的方法实现中混合在一起的时候,不变的行为就会在子类中重复出现。我们通过模板方法模式吧这些行为搬移到单一的地方,这样就帮子类摆脱重复不变行为的纠缠。
参考资料:程杰<大话设计模式>