十、结构型(外观模式)

外观模式(Facade Pattern)

概念

外观模式(Facade Pattern)是一种结构型设计模式,旨在为复杂子系统提供一个简化的统一接口。通过外观模式,客户端可以与子系统交互,而无需了解子系统的内部复杂性。这种模式为客户端屏蔽了复杂系统的细节,使得客户端使用系统时变得更简单。


应用场景

  1. 简化客户端与复杂系统的交互:在一个复杂的系统中,如果客户端需要与多个子系统进行交互,外观模式通过提供一个简化的接口,隐藏了系统的复杂性。例如,图形系统、数据库操作、第三方接口等往往有多个复杂的接口,外观模式可以为这些接口提供统一入口。

  2. 减少类之间的耦合:客户端只需与外观类交互,而不需要直接调用多个子系统接口,从而降低了客户端与子系统之间的耦合度,增强了系统的可维护性。

  3. 层次化结构:外观模式可以用于设计层次化系统,每一层提供一个外观类,减少上下层的相互依赖。例如,Web应用程序中,业务层可能会通过外观类来调用底层的持久化层和其他服务。


注意点

  • 外观类不应包含太多业务逻辑:外观类的职责应是简化接口,而不是实现复杂的业务逻辑。实际业务逻辑应由子系统负责处理。
  • 外观模式并不强制子系统内部结构的简化:它只是对客户端提供了一个简化的接口,子系统内部仍然可能非常复杂。
  • 可扩展性问题:如果子系统发生变化,外观类可能需要随着调整。

核心要素

  1. Facade(外观类):为客户端提供简化的接口,封装复杂的子系统接口调用。
  2. Subsystem(子系统类):复杂子系统的一部分,通常是多个类组成的系统,外观类通过这些子系统类完成各种功能。
  3. 客户端(Client):使用外观类来与子系统交互,客户端无需知道子系统的细节。

Java代码完整示例

java 复制代码
// 子系统A
class SubsystemA {
    public void operationA() {
        System.out.println("子系统A的操作");
    }
}

// 子系统B
class SubsystemB {
    public void operationB() {
        System.out.println("子系统B的操作");
    }
}

// 子系统C
class SubsystemC {
    public void operationC() {
        System.out.println("子系统C的操作");
    }
}

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

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

    // 提供简化的接口
    public void performOperation() {
        subsystemA.operationA();
        subsystemB.operationB();
        subsystemC.operationC();
    }
}

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

输出结果

子系统A的操作
子系统B的操作
子系统C的操作

各种变形用法完整示例

  1. 分层外观模式

    在复杂系统中,多个子系统可能会存在多层次的依赖关系,可以为每一层提供一个外观类。例如,在一个大型企业级系统中,可以有数据层、业务逻辑层和表示层的外观类。

    代码示例

    java 复制代码
    // 数据层外观类
    class DataLayerFacade {
        private SubsystemA subsystemA;
        private SubsystemB subsystemB;
    
        public DataLayerFacade() {
            subsystemA = new SubsystemA();
            subsystemB = new SubsystemB();
        }
    
        public void dataLayerOperation() {
            subsystemA.operationA();
            subsystemB.operationB();
        }
    }
    
    // 业务层外观类
    class BusinessLayerFacade {
        private DataLayerFacade dataLayerFacade;
        private SubsystemC subsystemC;
    
        public BusinessLayerFacade() {
            dataLayerFacade = new DataLayerFacade();
            subsystemC = new SubsystemC();
        }
    
        public void businessLayerOperation() {
            dataLayerFacade.dataLayerOperation();
            subsystemC.operationC();
        }
    }
    
    // 客户端
    public class ClientLayered {
        public static void main(String[] args) {
            BusinessLayerFacade businessLayerFacade = new BusinessLayerFacade();
            businessLayerFacade.businessLayerOperation();
        }
    }
  2. 双重外观模式

    双重外观模式是将多个外观模式结合使用,客户端可以选择使用不同的外观类来访问不同的子系统。例如,一个系统可能包含多个独立模块,每个模块有自己的外观类,客户端可以选择使用特定模块的外观类。

    代码示例

    java 复制代码
    // 外观A
    class FacadeA {
        private SubsystemA subsystemA;
        private SubsystemB subsystemB;
    
        public FacadeA() {
            subsystemA = new SubsystemA();
            subsystemB = new SubsystemB();
        }
    
        public void operationA() {
            subsystemA.operationA();
            subsystemB.operationB();
        }
    }
    
    // 外观B
    class FacadeB {
        private SubsystemC subsystemC;
    
        public FacadeB() {
            subsystemC = new SubsystemC();
        }
    
        public void operationB() {
            subsystemC.operationC();
        }
    }
    
    // 客户端
    public class ClientMultipleFacades {
        public static void main(String[] args) {
            FacadeA facadeA = new FacadeA();
            facadeA.operationA();
            
            FacadeB facadeB = new FacadeB();
            facadeB.operationB();
        }
    }
  3. 与单例模式结合的外观模式

    外观模式常与单例模式结合使用,以确保系统中的外观类只有一个实例,减少系统开销,确保统一的接口访问。

    代码示例

    java 复制代码
    // 外观类使用单例模式
    class SingletonFacade {
        private static SingletonFacade instance;
        private SubsystemA subsystemA;
        private SubsystemB subsystemB;
    
        private SingletonFacade() {
            subsystemA = new SubsystemA();
            subsystemB = new SubsystemB();
        }
    
        public static SingletonFacade getInstance() {
            if (instance == null) {
                instance = new SingletonFacade();
            }
            return instance;
        }
    
        public void performOperations() {
            subsystemA.operationA();
            subsystemB.operationB();
        }
    }
    
    // 客户端
    public class ClientSingletonFacade {
        public static void main(String[] args) {
            SingletonFacade facade = SingletonFacade.getInstance();
            facade.performOperations();
        }
    }

总结

外观模式的主要作用是简化客户端对复杂系统的访问。通过引入外观类,系统的可维护性、可扩展性和模块化得到了提升。装饰者模式和外观模式的不同之处在于,装饰者模式注重在运行时增加功能,而外观模式侧重于为子系统提供一个简化的接口。

相关推荐
无敌岩雀20 小时前
C++设计模式结构型模式———外观模式
c++·设计模式·外观模式
morning_judger4 天前
【设计模式系列】外观模式(十四)
java·设计模式·外观模式
zzzhpzhpzzz5 天前
设计模式——外观模式
设计模式·外观模式
Mr. zhihao5 天前
外观模式及运用场景
java·外观模式
小白6 天前
C# 结构型设计模式----外观模式
设计模式·外观模式
XYX的Blog7 天前
设计模式07-结构型模式(装饰模式/外观模式/代理模式/Java)
设计模式·代理模式·外观模式
且随疾风前行.14 天前
技术成神之路:设计模式(二十一)外观模式
设计模式·外观模式·1024程序员节
拥有一颗学徒的心1 个月前
设计模式——门面模式 | 外观模式
java·设计模式·团队开发·外观模式·设计规范
刷帅耍帅1 个月前
设计模式-外观模式
设计模式·外观模式