【设计模式】【结构型模式(Structural Patterns)】之外观模式(Facade Pattern)
1. 设计模式原理说明
外观模式(Facade Pattern) 是一种结构型设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。通过隐藏子系统的复杂性,外观模式简化了客户端对子系统的使用,提高了系统的易用性和降低了解耦程度。
主要角色
- Facade(外观):为子系统的类提供一个简化的接口。
- SubSystem Classes(子系统类):实现了子系统的功能,处理由 Facade 对象指派的工作。任何数目的子系统类都可以存在,它们不知道 Facade 的存在。
2. UML 类图及解释
UML 类图
+-----------------+ +-----------------+
| Facade | | SubSystemClassA |
|-----------------| |-----------------|
| - subsystemA: SubSystemClassA | | + operationA(): void|
| - subsystemB: SubSystemClassB | +-----------------+
| + operation(): void |
| + subOperationA(): void | +-----------------+
| + subOperationB(): void | | SubSystemClassB |
+-----------------+ | |-----------------|
| | + operationB(): void|
| +-----------------+
类图解释
- Facade:提供了一个简化的接口,用来访问子系统中的多个类。它内部包含了对各个子系统类的引用,并负责协调这些子系统类之间的交互。
- SubSystemClassA 和 SubSystemClassB:代表了子系统的不同部分,它们各自完成特定的功能。这些类对外部是不可见的,只有通过 Facade 提供的接口才能访问它们。
3. 代码案例及逻辑详解
Java 代码案例
// 子系统类 A
class SubSystemClassA {
public void operationA() {
System.out.println("SubSystemClassA operationA");
}
}
// 子系统类 B
class SubSystemClassB {
public void operationB() {
System.out.println("SubSystemClassB operationB");
}
}
// 外观
class Facade {
private SubSystemClassA subsystemA = new SubSystemClassA();
private SubSystemClassB subsystemB = new SubSystemClassB();
public void operation() {
subsystemA.operationA();
subsystemB.operationB();
}
}
// 客户端
public class Client {
public static void main(String[] args) {
Facade facade = new Facade();
facade.operation();
// 输出:
// SubSystemClassA operationA
// SubSystemClassB operationB
}
}
C++ 代码案例
#include <iostream>
// 子系统类 A
class SubSystemClassA {
public:
void operationA() {
std::cout << "SubSystemClassA operationA" << std::endl;
}
};
// 子系统类 B
class SubSystemClassB {
public:
void operationB() {
std::cout << "SubSystemClassB operationB" << std::endl;
}
};
// 外观
class Facade {
private:
SubSystemClassA subsystemA;
SubSystemClassB subsystemB;
public:
void operation() {
subsystemA.operationA();
subsystemB.operationB();
}
};
// 客户端
int main() {
Facade facade;
facade.operation();
// 输出:
// SubSystemClassA operationA
// SubSystemClassB operationB
return 0;
}
Python 代码案例
# 子系统类 A
class SubSystemClassA:
def operationA(self):
print("SubSystemClassA operationA")
# 子系统类 B
class SubSystemClassB:
def operationB(self):
print("SubSystemClassB operationB")
# 外观
class Facade:
def __init__(self):
self.subsystemA = SubSystemClassA()
self.subsystemB = SubSystemClassB()
def operation(self):
self.subsystemA.operationA()
self.subsystemB.operationB()
# 客户端
if __name__ == "__main__":
facade = Facade()
facade.operation()
# 输出:
# SubSystemClassA operationA
# SubSystemClassB operationB
Go 代码案例
package main
import "fmt"
// 子系统类 A
type SubSystemClassA struct{}
func (a *SubSystemClassA) OperationA() {
fmt.Println("SubSystemClassA operationA")
}
// 子系统类 B
type SubSystemClassB struct{}
func (b *SubSystemClassB) OperationB() {
fmt.Println("SubSystemClassB operationB")
}
// 外观
type Facade struct {
subsystemA *SubSystemClassA
subsystemB *SubSystemClassB
}
func NewFacade() *Facade {
return &Facade{
subsystemA: &SubSystemClassA{},
subsystemB: &SubSystemClassB{},
}
}
func (f *Facade) Operation() {
f.subsystemA.OperationA()
f.subsystemB.OperationB()
}
// 客户端
func main() {
facade := NewFacade()
facade.Operation()
// 输出:
// SubSystemClassA operationA
// SubSystemClassB operationB
}
4. 总结
外观模式 是一种结构型设计模式,它提供了一个统一的接口,用来访问子系统中的一群接口。通过隐藏子系统的复杂性,外观模式简化了客户端对子系统的使用,提高了系统的易用性和降低了系统的耦合度。
主要优点
- 简化了客户端的使用:通过提供一个简单的接口,客户端无需关心子系统的内部细节,从而简化了客户端的代码。
- 解耦了客户端和子系统:客户端只需要依赖于外观,而不需要直接依赖于子系统中的各个类,从而降低了系统的耦合度。
- 提高了子系统的独立性:子系统可以独立地发展和变化,而不影响到外观和客户端。
主要缺点
- 不符合开闭原则:如果子系统发生变化,外观类也需要相应地进行修改。
- 可能会导致外观类过于臃肿:如果子系统的功能非常复杂,外观类可能会变得非常庞大,不易维护。
适用场景
- 当需要为一个复杂的子系统提供一个简单接口时。
- 当客户端需要与多个子系统交互,但只希望暴露有限的接口时。
- 当需要减少系统之间或系统与其他系统之间的依赖关系时。