十、结构型(外观模式)

外观模式(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();
        }
    }

总结

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

相关推荐
nlog3n17 小时前
Java外观模式详解
java·开发语言·外观模式
Niuguangshuo19 小时前
Python 设计模式:外观模式
python·设计模式·外观模式
NorthCastle9 天前
设计模式-结构型模式-外观模式
java·设计模式·外观模式
系统工程实验室11 天前
设计模式之外观模式
设计模式·外观模式
Antonio91511 天前
【Q&A】外观模式在Qt中有哪些应用?
数据库·qt·外观模式
Hanson Huang11 天前
23种设计模式-外观(Facade)设计模式
java·设计模式·外观模式·结构型设计模式
wenbin_java19 天前
设计模式之外观模式:原理、实现与应用
设计模式·外观模式
seven97_top21 天前
【设计模式】从智能音箱到软件设计:探索外观模式的实际应用案例
设计模式·外观模式
没明白白21 天前
结构型模式之外观模式:让复杂系统变简单的利器
外观模式
码农的天塌了22 天前
Java设计模式之外观模式(Facacde Pattern)
java·设计模式·外观模式