大话设计模式-模板方法模式

来源:互联网 发布:手机可以注册淘宝店铺吗 编辑:程序博客网 时间:2024/06/06 01:05

本文转载自点击打开链接
需求
实现一份金庸知识考试的试卷。
实现
级别1

//学生甲抄的试卷类  public class TestPaperA  {    public void testQuestion1()    {        System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] "                + "a.球磨铸铁 b.马口铁 c.高速合金钥 d.碳素纤维");        System.out.println("答案:b");    }    public void testQuestion2()    {        System.out.println("杨过、程英、陆无双铲除了情花.造成[] " + "a.使这种植物不再害人 b.使一种珍稀物种灭绝 "                + "c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化");        System.out.println("答案:a");    }    public void testQuestion3()    {        System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] "                + "a.阿司匹林 b.牛黄解毒片 c.氟呱酸 d.让他们喝大量的生牛奶 e.以上全不对");        System.out.println("答案:c");    }  }  
//学生乙抄的试卷类  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("答案:b");    }    public void testQuestion3()    {        System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] "                + "a.阿司匹林 b.牛黄解毒片 c.氟呱酸 d.让他们喝大量的生牛奶 e.以上全不对");        System.out.println("答案:a");    }  } 
//客户端代码  public class Main  {    public static void main(String[] args)    {        System.out.println("学生甲抄的试卷:");        TestPaperA studentA = new TestPaperA();        studentA.testQuestion1();        studentA.testQuestion2();        studentA.testQuestion3();        System.out.println("学生乙抄的试卷:");        TestPaperA studentB = new TestPaperA();        studentB.testQuestion1();        studentB.testQuestion2();        studentB.testQuestion3();    }  }
学生甲和学生乙两个抄试卷类非常类似,除了答案不同之外,没有什么不一样的,这样写又容易错,又难以维护。老师出一份试卷,打印多份,让学生填答案即可。在这里应该把试题和答案分离,抽象一个父类,让两个子类去继承它,公共的试题代码写到父类中。
级别2
//试卷父类  public class TestPaper  {    public void testQuestion1()    {        System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] "                + "a.球磨铸铁 b.马口铁 c.高速合金钥 d.碳素纤维");    }    public void testQuestion2()    {        System.out.println("杨过、程英、陆无双铲除了情花.造成[] " + "a.使这种植物不再害人 b.使一种珍稀物种灭绝 "                + "c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化");    }    public void testQuestion3()    {        System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] "                + "a.阿司匹林 b.牛黄解毒片 c.氟呱酸 d.让他们喝大量的生牛奶 e.以上全不对");    }  }  
//学生甲抄的试卷  public class TestPaperA extends TestPaper  {    public void testQuestion1()    {        super.testQuestion1();        System.out.println("答案:b");    }    public void testQuestion2()    {        super.testQuestion2();        System.out.println("答案:b");    }    public void testQuestion3()    {        super.testQuestion3();        System.out.println("答案:b");    }  }  
//学生乙抄的试卷  public class TestPaperB extends TestPaper  {    public void testQuestion1()    {        super.testQuestion1();        System.out.println("答案:b");    }    public void testQuestion2()    {        super.testQuestion2();        System.out.println("答案:b");    }    public void testQuestion3()    {        super.testQuestion3();        System.out.println("答案:b");    }  }   
//客户端代码  public class Main  {    public static void main(String[] args)    {        System.out.println("学生甲抄的试卷:");        TestPaperA studentA = new TestPaperA();        studentA.testQuestion1();        studentA.testQuestion2();        studentA.testQuestion3();        System.out.println("学生乙抄的试卷:");        TestPaperA studentB = new TestPaperA();        studentB.testQuestion1();        studentB.testQuestion2();        studentB.testQuestion3();    }  }  
相同的东西还是有,比如都有super.testQuestion1()和System.out.println("答案:b"),除了选项的abcd,其他都是重复的。我们既然用了继承,并且肯定这个继承是有意义的,就应该要成为子类的模板,所有重复的代码都应该要上升到父类去,而不是让每个子类都去重复。当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理。
级别3
//试题父类  public class TestPaper  {    public void testQuestion1()    {        System.out.println("杨过得到,后来给了郭靖,练成倚天剑、屠龙刀的玄铁可能是[] "                + "a.球磨铸铁 b.马口铁 c.高速合金钥 d.碳素纤维");        System.out.println("答案:" + answer1());    }    public void testQuestion2()    {        System.out.println("杨过、程英、陆无双铲除了情花.造成[] " + "a.使这种植物不再害人 b.使一种珍稀物种灭绝 "                + "c.破坏了那个生物圈的生态平衡 d.造成该地区沙漠化");        System.out.println("答案:" + answer2());    }    public void testQuestion3()    {        System.out.println("蓝凤凰致使华山师徒、桃谷六仙呕吐不止,如果你是大夫,会给他们开什么药[] "                + "a.阿司匹林 b.牛黄解毒片 c.氟呱酸 d.让他们喝大量的生牛奶 e.以上全不对");        System.out.println("答案:" + answer3());    }    protected String answer1()    {        return "";    }    protected String answer2()    {        return "";    }    protected String answer3()    {        return "";    }    //这些方法存在的目的就是给继承的子类重写,因为这里每个人的答案都是不同的}  
public class TestPaperA extends TestPaper  {      protected String answer1()      {          return "b";      }      protected String answer2()      {          return "c";      }      protected String answer3()      {          return "a";      }  }
public class TestPaperB extends TestPaper  {      protected String answer1()      {          return "c";      }       protected String answer2()      {          return "a";      }      protected String answer3()      {          return "a";      }  }
public class Main  {      public static void main(String[] args)      {          System.out.println("学生甲抄的试卷:");          TestPaper studentA = new TestPaperA();          studentA.testQuestion1();          studentA.testQuestion2();          studentA.testQuestion3();          System.out.println("学生乙抄的试卷:");          TestPaper studentB = new TestPaperB();          studentB.testQuestion1();          studentB.testQuestion2();          studentB.testQuestion3();      }  }
模板方法模式,定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。


//AbstractClass是抽象类,其实也就是一抽象模板,定义并实现了一个模板方法public abstract class AbstractClass  {    public abstract void primitiveOperation1();    public abstract void primitiveOperation2();    public void templateMethod()    {        primitiveOperation1();        primitiveOperation2();    }  }  //ConcreteClass,实现父类所定义的一个或多个抽象方法 public class ConcreteClassA extends AbstractClass  {    @Override    public void primitiveOperation1()    {        System.out.println("具体类A方法1实现");    }    @Override    public void primitiveOperation2()    {        System.out.println("具体类A方法2实现");    }  }  public class ConcreteClassB extends AbstractClass  {    @Override    public void primitiveOperation1()    {        System.out.println("具体类B方法1实现");    }    @Override    public void primitiveOperation2()    {        System.out.println("具体类B方法2实现");    }  }  //客户端代码  public class Main  {    public static void main(String[] args)    {        AbstractClass c;        c = new ConcreteClassA();        c.templateMethod();        c = new ConcreteClassB();        c.templateMethod();    }  }    



0 1