设计模式- 外观模式(Facade Pattern)结构|原理|优缺点|场景|示例

时间:2024-04-23 12:32:53

                            ​​​​​​​        设计模式(分类)        设计模式(六大原则)   

    创建型(5种)        工厂方法         抽象工厂模式        单例模式        建造者模式        原型模式

    结构型(7种)        适配器模式        装饰器模式        代理模式        ​​​​​​外观模式      桥接模式        组合模式       享元模式

    行为型(11种)      策略模式        模板方法模式        观察者模式        迭代器模式        责任链模式        命令模式

                                   备忘录模式          状态模式          访问者模式        中介者模式    


外观模式(Facade Pattern)是一种结构型设计模式,其目的是为子系统提供一个统一的、更高级别的接口,使得客户端能够更容易地与子系统进行交互,而不必了解子系统的内部细节。外观模式通过创建一个外观类(Facade),封装了子系统中的复杂接口或多个子系统接口,提供一个更简洁、更易于使用的接口给客户端,从而降低了客户端与子系统之间的耦合度。

模式结构

外观模式通常包含以下角色:

  1. 子系统(Subsystem):由多个类组成的模块或系统,每个类负责子系统的一部分功能。子系统并不知道外观的存在,对于子系统而言,外观只是另一个客户端。

  2. 外观(Facade):为子系统提供一个统一的接口,定义了一个高层接口,使得子系统更加容易使用。外观知道哪些子系统类负责处理请求,将客户端的请求转发给适当的子系统对象处理,并可以决定哪些子系统对象参与处理请求。

工作原理

  • 客户端:通过外观类与子系统进行交互,无需直接与子系统内部的复杂接口或多个接口打交道,简化了客户端的使用。
  • 外观:为客户端提供一个简单易用的接口,接收客户端的请求,并将请求转发给相应的子系统对象进行处理。外观可以协调子系统对象的交互,或者添加额外的逻辑来处理请求。
  • 子系统:负责实现具体的业务逻辑。子系统并不知道外观的存在,它们独立于外观进行开发和演化。

优缺点

优点
  • 简化接口:为子系统提供了一个简化的接口,降低了客户端与子系统的耦合度。
  • 减少复杂性:隐藏了子系统的复杂性,使得客户端无需了解子系统的内部结构和实现细节。
  • 易于使用和扩展:客户端只需与外观交互,简化了系统的使用,同时新增或修改子系统时,只需调整外观类,不影响客户端代码。
缺点
  • 违反开闭原则:若新增子系统功能,可能需要修改外观类,这在一定程度上违反了“开闭原则”。
  • 可能增加系统的复杂性:若设计不当,外观类可能会过于庞大,成为另一个难以维护的中心点。

适用场景

  • 子系统接口复杂,不易理解和使用:当子系统包含多个接口,或者接口方法众多且使用复杂时,可以使用外观模式提供一个简单易用的接口。
  • 需要简化并统一子系统接口:在不同子系统之间存在大量交互,或者客户端需要与多个子系统交互时,可以通过外观模式提供一个统一的接口。
  • 希望减少客户端与子系统之间的耦合:通过外观模式隔离客户端与子系统的直接联系,使得两者可以独立演化。

代码示例(以Java为例)

// 子系统类
class SubsystemA {
    public void operation() {
        System.out.println("Subsystem A performing operation.");
    }
}

class SubsystemB {
    public void operation() {
        System.out.println("Subsystem B performing operation.");
    }
}

class SubsystemC {
    public void operation() {
        System.out.println("Subsystem C performing operation.");
    }
}

// 外观类
class Facade {
    private SubsystemA subsystemA;
    private SubsystemB subsystemB;
    private SubsystemC subsystemC;

    public Facade() {
        subsystemA = new SubsystemA();
        subsystemB = new SubsystemB();
        subsystemC = new SubsystemC();
    }

    public void performComplexOperation() {
        System.out.println("Starting complex operation...");
        subsystemA.operation();
        subsystemB.operation();
        subsystemC.operation();
        System.out.println("Complex operation completed.");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.performComplexOperation();
    }
}

在这个Java示例中:

  • SubsystemASubsystemBSubsystemC类代表子系统中的不同部分,各自实现了一个operation()方法。
  • Facade类作为外观,封装了子系统类,提供了performComplexOperation()方法,该方法调用子系统的operation()方法以执行复杂的操作序列。
  • 客户端代码通过Facade对象调用performComplexOperation()方法,无需直接与子系统类交互,简化了客户端代码。

代码示例(以Python为例)

# 子系统类
class SubsystemA:
    def operation(self):
        print("Subsystem A performing operation.")

class SubsystemB:
    def operation(self):
        print("Subsystem B performing operation.")

class SubsystemC:
    def operation(self):
        print("Subsystem C performing operation.")

# 外观类
class Facade:
    def __init__(self):
        self.subsystem_a = SubsystemA()
        self.subsystem_b = SubsystemB()
        self.subsystem_c = SubsystemC()

    def perform_complex_operation(self):
        print("Starting complex operation...")
        self.subsystem_a.operation()
        self.subsystem_b.operation()
        self.subsystem_c.operation()
        print("Complex operation completed.")

# 客户端代码
def main():
    facade = Facade()
    facade.perform_complex_operation()

if __name__ == "__main__":
    main()

 在这个Python示例中:

  • SubsystemASubsystemBSubsystemC类代表子系统中的不同部分,各自实现一个operation()方法。
  • Facade类作为外观,封装了子系统类,提供了perform_complex_operation()方法,该方法调用子系统的operation()方法以执行复杂的操作序列。
  • 客户端代码通过Facade对象调用perform_complex_operation()方法,无需直接与子系统类交互,简化了客户端代码。