面向对象(下)-模版方法的设计模式其应用场景
多态的应用:模版方法设计模式(TemplateMethod)
抽象类体现的就是一种模版模式的设计,抽象类作为多个子类的通用模版,子类在抽象类的基础上进行扩展、改造,单子类总体上会保留抽象类的行为方式。
解决的问题:
-
当功能内部一部分实现是确定的,一部分实现是不确定的。这时可以把不确定的部分暴露出去,让子类去实现。
-
换句话说,在软件开发中实现一个算法时,
整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模版模式。
模版模式举例
spendTime是一个获取代码执行耗时的方法。获取代码耗时步骤固定、通用,即获取代码运行前后时间相减即可,但是具体运行什么代码,暂时不确定。那么久可以把确定的做成模版,不确定的设计为抽象方法供子类调用。
运行时,只需实现不确定的代码,即可获取代码执行时间了。
判断 97 是否为质数:
√97 ≈ 9.85
只需要检查:2, 3, 4, 5, 6, 7, 8, 9
不需要检查 10, 11, 12, ... 96
验证:如果 97 能被 11 整除(11 > √97),那么商是 97÷11 ≈ 8.8,不是整数,那我们只要检查8.8(8.8 < √97》)就行了。实际上,要是有大于√97的因子,其对应的因子一定小于√97,但我们检查小于√97的数时已经能发现了。
java
public class TemplateTest {
public static void main(String[] args) {
new Template() {
@Override
void code() {
// 查找1000以内所有的质数,只能被1和本身除尽
for (int i = 2; i <= 1000; i++){
boolean isFlag = true;
// 如果一个数不是质数,它必定能被 ≤√i 的某个整数整除
for (int j = 2; j <= Math.sqrt(i); j++) {
if (i % j == 0) {
isFlag = false;
break; // 发现因子,说明不是质子,立即跳出
}
}
if (isFlag) {
System.out.print(i + "; ");
}
}
}
}.spendTime(); // 获取运行代码的时间
}
}
abstract class Template{
// 运行某段代码花费的时间:整体步骤很固定、通用
void spendTime() {
long start = System.currentTimeMillis(); // 获取运行代码之前的时间
code(); // 运行代码,具体什么代码不确定
long end = System.currentTimeMillis();
System.out.println("\n运行代码花费的时间:" + (end - start));
}
abstract void code();
}
2; 3; 5; 7; 11; 13; 17; 19; 23; 29; 31; 37; 41; 43; 47; 53; 59; 61; 67; 71; 73; 79; 83; 89; 97; 101; 103; 107; 109; 113; 127; 131; 137; 139; 149; 151; 157; 163; 167; 173; 179; 181; 191; 193; 197; 199; 211; 223; 227; 229; 233; 239; 241; 251; 257; 263; 269; 271; 277; 281; 283; 293; 307; 311; 313; 317; 331; 337; 347; 349; 353; 359; 367; 373; 379; 383; 389; 397; 401; 409; 419; 421; 431; 433; 439; 443; 449; 457; 461; 463; 467; 479; 487; 491; 499; 503; 509; 521; 523; 541; 547; 557; 563; 569; 571; 577; 587; 593; 599; 601; 607; 613; 617; 619; 631; 641; 643; 647; 653; 659; 661; 673; 677; 683; 691; 701; 709; 719; 727; 733; 739; 743; 751; 757; 761; 769; 773; 787; 797; 809; 811; 821; 823; 827; 829; 839; 853; 857; 859; 863; 877; 881; 883; 887; 907; 911; 919; 929; 937; 941; 947; 953; 967; 971; 977; 983; 991; 997;
运行代码花费的时间:17