设计模式--模板方法&外观模式

模板方法模式

场景:需使用代码方式实现,考完试后,将各个学生的试卷及答案誊抄一份。

假如有两个学生的试卷誊抄完毕.

java 复制代码
// 学生A
public class TestPaperA {
    // 试题1
    public void testQuestion1() {
        System.out.println("问题一:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 A");
    }
    // 试题2
    public void testQuestion2() {
        System.out.println("问题二:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 A");
    }
    // 试题3
    public void testQuestion3() {
        System.out.println("问题三:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 A");
    }
}
java 复制代码
// 学生B
public class TestPaperB {
    // 试题1
    public void testQuestion1() {
        System.out.println("问题一:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 B");
    }
    // 试题2
    public void testQuestion2() {
        System.out.println("问题二:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 B");
    }
    // 试题3
    public void testQuestion3() {
        System.out.println("问题三:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 B");
    }
}
  • 客户端
java 复制代码
System.out.println("学生A的试卷");
TestPaperA a = new TestPaperA();
a.testQuestion1();
a.testQuestion2();
a.testQuestion3();

System.out.println("学生B的试卷");
TestPaperB b = new TestPaperB();
b.testQuestion1();
b.testQuestion2();
b.testQuestion3();

一眼看出,很多重复的代码,直接进行提炼抽离。此例中,试卷都是一样的,而答案是不同的,我们直接将重复的代码提炼,然后学生去继承它即可。

  • 试卷类
java 复制代码
// 试卷类
public abstract class TestPaper { 
    // 3道题的答案
    protected abstract String answer1();
    protected abstract String answer2();
    protected abstract String answer3();

    // 试题1
    public void testQuestion1() {
        System.out.println("问题一:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 " + answer1());
    }
    // 试题2
    public void testQuestion2() {
        System.out.println("问题二:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 " + answer2());
    }
    // 试题3
    public void testQuestion3() {
        System.out.println("问题三:XXXXXXXX[] A.xx B.xx C.xx D.xx ");
        System.out.println("答案 " + answer3());
    }  
}

学生类只需要继承它,然后填写自己的答案即可。因为父类已经建立好了所有重复的模板

java 复制代码
// 学生A
public class TestPaperA extends TestPaper{
    @Override
    protected String answer1() {
        return "A";
    }
    @Override
    protected String answer2() {
        return "A";
    }
    @Override
    protected String answer3() {
        return "A";
    }
}
  • 客户端
java 复制代码
System.out.println("学生A的试卷");
TestPaper a = new TestPaperA();
a.testQuestion1();
a.testQuestion2();
a.testQuestion3();

那么上述的例子中,用的一种设计模式就是模板方法模式。定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重新定义该算法的某些特定步骤。

结构图及代码示例如下:

java 复制代码
public abstract class AbstractClass {
    
    // 模板方法(所有重复的代码都放入这里)
    public void templateMethod() {
        ...
    }
    
    // 子类的特定实现
    public abstract void primitiveOperation1();
    public abstract void primitiveOperation2();
    
}
  • 子类
java 复制代码
public class ConcreteClassA extends AbstractClass {
    @Override
    public void primitiveOperation1() {
        System.out.println("A类具体实现一");
    }

    @Override
    public void primitiveOperation2() {
        System.out.println("A类具体实现二");
    }
}

模板方法是通过把不变行为搬到父类(超类),去除子类中重复代码来体现它的优势。

模板方法是提供了一个代码复用平台。

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

外观模式

以一个股票买卖的例子来理解一下,现在有股票、国债、房产,买入卖出代码如下:

  • 股票
java 复制代码
// 股票1
public class Stock1 {
    public void buy() {
        System.out.println("股票1买入");
    }
    public void sell() {
        System.out.println("股票1卖出");
    }
}
// 股票2
class Stock2 {
    public void buy() {
        System.out.println("股票2买入");
    }
    public void sell() {
        System.out.println("股票2卖出");
    }
}
  • 国债、房产
java 复制代码
// 国债1
public class NationalDebt1 {
    public void buy() {
        System.out.println("国债买入");
    }
    public void sell() {
        System.out.println("国债卖出");
    }
}

// 房产
class Realty1 {
    public void buy() {
        System.out.println("房产买入");
    }
    public void sell() {
        System.out.println("房产卖出");
    }
}
  • 客户端
java 复制代码
Stock1 stock1 = new Stock1();
Stock2 stock2 = new Stock2();
NationalDebt1 nd1 = new NationalDebt1();
Realty1 rt1 = new Realty1();

// 买入
stock1.buy();
stock2.buy();
nd1.buy();
rt1.buy();

// 卖出
stock1.sell();
stock2.sell();
nd1.sell();
rt1.sell();

外观模式

增加一个基金类,结构图

  • 基金类代码
java 复制代码
public class Fund {
    Stock1 stock1;
    Stock2 stock2;
    NationalDebt1 nd1;
    Realty1 rt1;
    public Fund() {
        stock1 = new Stock1();
        stock2 = new Stock2();
        nd1 = new NationalDebt1();
        rt1 = new Realty1();
    }
    public void buyFund() {
        stock1.buy();
        stock2.buy();
        nd1.buy();
        rt1.buy();
    }
    public void sellFund() {
        stock1.sell();
        stock2.sell();
        nd1.sell();
        rt1.sell();
    }
    
}
  • 客户端
java 复制代码
Fund fund = new Fund();
fund.buyFund();

fund.sellFund();

外观模式:为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

首先在设计阶段,应该有意识将不同的两个层进行分离。其次,在开发阶段,子系统往往因为不断的重构演化而变得越来越复杂,增加外观模式可以提供一个简单的接口减少它们之间的依赖。

还可以在新系统中使用外观模式,创建一个Facade类(外观模式类),来提供设计粗糙或高复杂度的遗留代码的比较清晰简单的接口,让新系统与Facade对象交互,Facade与遗留代码交互完成复杂的工作。

相关推荐
瞎姬霸爱.10 小时前
设计模式-七个基本原则之一-里氏替换原则
java·设计模式·里氏替换原则
monkey_meng10 小时前
【Rust设计模式之建造者模式】
后端·设计模式·rust·建造者模式
BIGSHU092317 小时前
游戏中的设计模式及杂项
游戏·设计模式
L_cl19 小时前
Python学习从0到1 day27 Python 高阶技巧 ③ 设计模式 — 单例模式
学习·单例模式·设计模式
CV猿码人20 小时前
设计模式-命令模式
设计模式·命令模式
编程、小哥哥1 天前
设计模式之工厂方法模式
java·设计模式·工厂方法模式
WaaTong1 天前
《重学Java设计模式》之 工厂方法模式
java·设计模式·工厂方法模式
努力编程的阿伟1 天前
软件工程中的创建型设计模式:工厂方法模式与抽象工厂模式
设计模式·软件工程·抽象工厂模式
孤邑2 天前
【设计模式】观察者模式
c++·笔记·学习·观察者模式·设计模式
hello world smile2 天前
Flutter 中的那些设计模式的写法(持续更新)
android·flutter·设计模式·移动开发