考题抄错会做也白搭——模板方法模式

考题抄错会做也白搭——模板方法模式

大鸟说道:让小菜写一个抄题目的程序。

重复 = 易错 + 难改

在这里插入图片描述

  • 甲的试卷
package template01;

public class TestPaperA {
    public void testQuestion1(){
        System.out.println("下列色彩由化学变化引起的是()\n A:节日的礼花\tB:夜晚的霓虹灯\tC:雨后的彩虹\tD:彩色的图画");
        System.out.println("ans : A");
    }

    public void testQuestion2(){
        System.out.println("下列物质种前者是混合物,后者是化合物的是()\nA:水 空气\tB:自来水 氧气\tC:矿泉水 冰水混合物\tD:高锰酸钾 双氧水");
        System.out.println("ans: C");
    }

    public void testQuestion3(){
        System.out.println("保持氧气化学性质的最小粒子是()\nA:氧原子\tB:氧气\tC:氧分子\tD:氧元素");
        System.out.println("A");
    }

}
  • 乙的试卷
package template01;

public class TestPaperB {
    public void testQuestion1(){
        System.out.println("下列色彩由化学变化引起的是()\n A:节日的礼花\tB:夜晚的霓虹灯\tC:雨后的彩虹\tD:彩色的图画");
        System.out.println("ans : C");
    }

    public void testQuestion2(){
        System.out.println("下列物质种前者是混合物,后者是化合物的是()\nA:水 空气\tB:自来水 氧气\tC:矿泉水 冰水混合物\tD:高锰酸钾 双氧水");
        System.out.println("ans: A");
    }

    public void testQuestion3(){
        System.out.println("保持氧气化学性质的最小粒子是()\nA:氧原子\tB:氧气\tC:氧分子\tD:氧元素");
        System.out.println("B");
    }
}
  • 客户端
package template01;

public class Client {
    public static void main(String[] args) {
        TestPaperA stu1 = new TestPaperA();
        TestPaperB stu2 = new TestPaperB();

        stu1.testQuestion1();
        stu1.testQuestion2();
        stu1.testQuestion3();

        System.out.println("------------");

        stu2.testQuestion1();
        stu2.testQuestion2();
        stu2.testQuestion3();

    }
}
/* out:
下列色彩由化学变化引起的是()
 A:节日的礼花	B:夜晚的霓虹灯	C:雨后的彩虹	D:彩色的图画
ans : A
下列物质种前者是混合物,后者是化合物的是()
A:水 空气	B:自来水 氧气	C:矿泉水 冰水混合物	D:高锰酸钾 双氧水
ans: C
保持氧气化学性质的最小粒子是()
A:氧原子	B:氧气	C:氧分子	D:氧元素
A
------------
下列色彩由化学变化引起的是()
 A:节日的礼花	B:夜晚的霓虹灯	C:雨后的彩虹	D:彩色的图画
ans : C
下列物质种前者是混合物,后者是化合物的是()
A:水 空气	B:自来水 氧气	C:矿泉水 冰水混合物	D:高锰酸钾 双氧水
ans: A
保持氧气化学性质的最小粒子是()
A:氧原子	B:氧气	C:氧分子	D:氧元素
B
*/

甲乙两个类非常相似,只有答案不同,这么写容易出错,还不好维护。

提炼代码

  • 试卷父类
package template02;

public class TestPaper {
    public void testQuestion1(){
        System.out.println("下列色彩由化学变化引起的是()\n A:节日的礼花\tB:夜晚的霓虹灯\tC:雨后的彩虹\tD:彩色的图画");
    }

    public void testQuestion2(){
        System.out.println("下列物质种前者是混合物,后者是化合物的是()\nA:水 空气\tB:自来水 氧气\tC:矿泉水 冰水混合物\tD:高锰酸钾 双氧水");
    }

    public void testQuestion3(){
        System.out.println("保持氧气化学性质的最小粒子是()\nA:氧原子\tB:氧气\tC:氧分子\tD:氧元素");
    }
}
  • 试卷子类
package template02;

public class TestPaperA extends TestPaper{
    @Override
    public void testQuestion1() {
        super.testQuestion1();
        System.out.println("ans:A");
    }

    @Override
    public void testQuestion2() {
        super.testQuestion2();
        System.out.println("ans:B");
    }

    @Override
    public void testQuestion3() {
        super.testQuestion3();
        System.out.println("ans:C");
    }
}


public class TestPaperB extends TestPaper{
    @Override
    public void testQuestion1() {
        super.testQuestion1();
        System.out.println("ans:B");
    }

    @Override
    public void testQuestion2() {
        super.testQuestion2();
        System.out.println("ans:C");
    }

    @Override
    public void testQuestion3() {
        super.testQuestion3();
        System.out.println("ans:A");
    }
}

但是子类中还有大量输出答案的语句 System.out.println("ans:C");

  • 继承要有意义父类就得成为子类的模板,把所有重复的代码都写道父类,而不是让每个子类去重复。

模范方法实现

在这里插入图片描述

  • 试卷父类
package template03;

public abstract class TestPaper {
    public void testQuestion1(){
        System.out.println("下列色彩由化学变化引起的是()\n A:节日的礼花\tB:夜晚的霓虹灯\tC:雨后的彩虹\tD:彩色的图画");
        System.out.println("ans:" + ans01());
    }

    public void testQuestion2(){
        System.out.println("下列物质种前者是混合物,后者是化合物的是()\nA:水 空气\tB:自来水 氧气\tC:矿泉水 冰水混合物\tD:高锰酸钾 双氧水");
        System.out.println("ans:" + ans02());
    }

    public void testQuestion3(){
        System.out.println("保持氧气化学性质的最小粒子是()\nA:氧原子\tB:氧气\tC:氧分子\tD:氧元素");
        System.out.println("ans:" + ans03());
    }

    // 子类必须重写“答案”
    public abstract String ans01();

    public abstract String ans02();

    public abstract String ans03();
}
  • 试卷子类
package template03;

public class TestPaperA extends TestPaper {
    @Override
    public String ans01() {
        return "A";
    }

    @Override
    public String ans02() {
        return "B";
    }

    @Override
    public String ans03() {
        return "C";
    }
}


public class TestPaperB extends TestPaper {

    @Override
    public String ans01() {
        return "B";
    }

    @Override
    public String ans02() {
        return "C";
    }

    @Override
    public String ans03() {
        return "C";
    }
}
  • 客户端
package template03;


public class Client {
    public static void main(String[] args) {
        // 多态
        TestPaper stu1 = new TestPaperA();
        TestPaper stu2 = new TestPaperB();

        stu1.testQuestion1();
        stu1.testQuestion2();
        stu1.testQuestion3();

        System.out.println("------------");

        stu2.testQuestion1();
        stu2.testQuestion2();
        stu2.testQuestion3();
    }
}
/* out:
下列色彩由化学变化引起的是()
 A:节日的礼花	B:夜晚的霓虹灯	C:雨后的彩虹	D:彩色的图画
ans:A
下列物质种前者是混合物,后者是化合物的是()
A:水 空气	B:自来水 氧气	C:矿泉水 冰水混合物	D:高锰酸钾 双氧水
ans:B
保持氧气化学性质的最小粒子是()
A:氧原子	B:氧气	C:氧分子	D:氧元素
ans:C
------------
下列色彩由化学变化引起的是()
 A:节日的礼花	B:夜晚的霓虹灯	C:雨后的彩虹	D:彩色的图画
ans:B
下列物质种前者是混合物,后者是化合物的是()
A:水 空气	B:自来水 氧气	C:矿泉水 冰水混合物	D:高锰酸钾 双氧水
ans:C
保持氧气化学性质的最小粒子是()
A:氧原子	B:氧气	C:氧分子	D:氧元素
ans:C
*/

模板方法模式

模板方法模式:定义一个操作中的算法骨架,将一些具体的步骤延迟到子类中去做。

模板方法使得子类可以不改变算法结构,即重新定义该算法中的某些步骤。

在这里插入图片描述

  • 抽象类
package template04;

public abstract class AbstractClass {
    // 算法骨架,某些算法的具体实现交给子类
    public void template(){
        primitiveOperation1();
        primitiveOperation2();
        primitiveOperation3();
    }

    public abstract void primitiveOperation1();
    public abstract void primitiveOperation2();
    public void primitiveOperation3(){
        System.out.println("这里是公有的操作");
    }
}
  • 具体子类
package template04;

public class ConcreteClass1 extends AbstractClass{
    @Override
    public void primitiveOperation1() {
        System.out.println("1 的具体操作");
    }

    @Override
    public void primitiveOperation2() {
        System.out.println("1 的具体操作");
    }
}


public class ConcreteClass2 extends AbstractClass{
    @Override
    public void primitiveOperation1() {
        System.out.println("2 的具体操作");
    }

    @Override
    public void primitiveOperation2() {
        System.out.println("2 的具体操作");
    }
}

  • 客户端
package template04;

public class Client {
    public static void main(String[] args) {
        AbstractClass c1 = new ConcreteClass1();
        AbstractClass c2 = new ConcreteClass2();

        c1.template();
        c2.template();
    }
}
/* out:
1 的具体操作
1 的具体操作
这里是公有的操作
2 的具体操作
2 的具体操作
这里是公有的操作
*/

模板方法模式特点

  • 把不变的方法放到父类,去除子类重复的代码。
  • 当不变的行为和可变的行为都出现在子类中时,不变的行为就会在子类中重复出现。我们需要将这些行为搬移到抽象父类,不变的行为就在父类写死,可变的行为交给子类来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值