设计模式-外观模式(Facade)
定义
“为子系统定义一组统一的接口,这个高级的接口会让子系统更容易被使用”
当我们能够利用简单的行为来操作一个复杂的系统时,当下所使用的接口,就是以外观模式来定义的高级接口。
实现
外观模式的重点在于,将系统内部的互动细节隐藏起来,并提供一个简单方便的接口;之后客户端只需要通过这个接口,就可以操作一个复杂系统并让其顺利运行。
类图
说明
- Facade(外观)
为多个子系统提供一个对外的访问接口; - Client(客户)
通过Facade访问其他子系统的功能; - SubSystem_X(子系统)
实现系统的部分功能,客户可以通过Facade访问它;
代码
下列代码在unity环境下编写运行
using UnityEngine;
//测试段
public class Facade_UnitTest : MonoBehaviour
{
Client client;
void Awake()
{
client = new Client();
client.Initial();
}
void Start()
{
client.GetSubAction();
}
}
//客户
public class Client
{
Facade face;
//通过Facade调用子系统的功能
public void Initial()
{
face = new Facade();
face.Initial();
}
public void GetSubAction()
{
//客户Client并没有与子系统建立任何联系,通过Facade来调用子系统的功能
//单向调用,子系统并不能调用客户Client的功能
face.Action();
}
}
public class Facade
{
private SubSystem_A subSystem_A;
private SubSystem_B subSystem_B;
public void Initial()
{
subSystem_A = new SubSystem_A();
subSystem_B = new SubSystem_B();
}
public void StateBegin()
{
subSystem_A.Begin();
subSystem_B.Begin();
}
public void Action()
{
subSystem_A.Action();
subSystem_B.Action();
}
}
public abstract class SubSystem
{
protected abstract void Initial();//声明为abstract子类必须重写,无方法体
public virtual void Begin() { }
public virtual void End() { }
public virtual void Update() { }
public virtual void Action() //声明为virtual子类按需重写
{
Debug.Log("系统执行一项操作");
}
}
public class SubSystem_A : SubSystem
{
protected override void Initial()
{
}
public override void Action()
{
base.Action();
Debug.Log("子系统A执行一项操作");
}
}
public class SubSystem_B : SubSystem
{
protected override void Initial()
{
}
}
与其他模式
- 与中介者模式
首先中介者模式是行为型模式,外观模式为结构型模式;
外观模式是将子系统集中在Facade接口中,其目的是提供一个单一的操作接口来调用子系统的功能,并不用关心子系统的运行,达到利用简单的行为来操作复杂的系统;
中介者模式是同事双方的交互通过中介者来完成;
外观模式中,客户只能通过Facade来调用子系统的功能,是单向的,子系统并不能调用客户的功能;而中介者模式则是双向的,同事之间都可以有相互的交互需求; - 与单例模式
可以根据需求将Facade设置为单例模式,便于管理和获取外观模式的入口;
小结
- 将复杂的子系统沟通交给单一的一个类来负责,并提供单一界面给客户端使用,使客户减少对系统的耦合度是外观模式的优点;
- 注意
由于将所以子系统集中在Facade接口类中,最终会导致Facde接口类过于庞大且难以维护。
当发生这种情况时,可以重构Facade接口类,将功能相近的子系统进行整合,以减少内部系统的依赖性,或是整合其他设计模式来减少Facade接口类的过度膨胀;