模式简介
门面(外观)模式是一种结构型设计模式,可用于调用者与内部系统的解耦,能够对复杂业务的接口进行简化,同时也可以避免内部系统中各个子系统之间的直接依赖。
常见的应用场景:复杂系统的接口简化、为遗留系统提供接口、库或框架接口的设计、多层架构中的隔离、子系统之间的解耦等。
模式结构
-
Facade(外观): 外观类是外观模式的核心,它提供了一个简化的接口,隐藏了系统内部子系统的复杂性。客户端通过与外观类进行交互来使用系统。
-
Subsystem(子系统): 子系统是系统内部的一组类或模块,负责实际完成系统的各个功能。这些功能可能会被外观类封装起来,对客户端不可见。
-
Client(客户端): 客户端是使用外观模式的地方。客户端通过与外观类交互来实现其功能,而不直接与系统的子系统进行交互。
工作原理
-
客户端通过外观类进行操作: 客户端不直接与系统的子系统进行交互,而是通过与外观类进行交互来完成操作。外观类提供了一个简单而一致的接口,隐藏了系统的复杂性。
-
外观类调用相关子系统: 外观类知道如何调用系统中的各个子系统,以完成客户端请求。外观类可能需要协调多个子系统的工作,但客户端不需要知道这些细节。
-
子系统处理具体任务: 实际的工作由子系统来完成。每个子系统负责执行一个特定的任务,这些任务可能相互关联,但客户端不需要关心这些关联关系。
-
客户端获得简化的接口: 通过外观模式,客户端获得了一个简化的、高层次的接口,使其更容易使用系统。客户端不必了解系统的内部结构,只需与外观类进行交互即可。
代码示例(C#)
提示:可在本栏目的资源篇“设计模式代码示例合集”下载所有完整代码资源。
系统:Systems.cs
namespace FacadePattern;
// 订单系统
class OrderSystem
{
public void SubmitOrder()
{
Console.WriteLine("已发送订单给商家。");
}
public void CancleOrder()
{
Console.WriteLine("已取消订单,并告知商家。");
}
}
// 物流系统
class LogisticsSystem
{
public void SendGood()
{
Console.WriteLine("商家已发送货物。");
}
public void StopSendGood()
{
Console.WriteLine("商家已停止发送货物。");
}
}
// 支付系统
class PaymentSystem
{
public void Pay()
{
Console.WriteLine("顾客已支付订单。");
}
public void ReturnMoney()
{
Console.WriteLine("支付款已退还给顾客。");
}
}
门面模式:FacadePattern.cs
namespace FacadePattern;
// 门面模式
class FacadePatternManager
{
private OrderSystem orderSystem;
private LogisticsSystem logisticsSystem;
private PaymentSystem paymentSystem;
public FacadePatternManager()
{
orderSystem = new OrderSystem();
logisticsSystem = new LogisticsSystem();
paymentSystem = new PaymentSystem();
}
// 完成商品购买
public void Shopping()
{
paymentSystem.Pay();
orderSystem.SubmitOrder();
logisticsSystem.SendGood();
}
// 取消商品购买
public void Cancle()
{
orderSystem.CancleOrder();
logisticsSystem.StopSendGood();
paymentSystem.ReturnMoney();
}
}
测试代码:Program.cs
// ************* 6.门面模式测试 **************
using FacadePattern;
FacadePatternManager facadePattern = new FacadePatternManager();
facadePattern.Shopping();
Console.WriteLine("---------------------------------------------");
facadePattern.Cancle();
代码解说
上述代码简单模拟了网上购物中购物和取消购物的业务逻辑。其中购物的逻辑是顾客在选定好指定的商品后进行支付,完成支付后订单将被发送给商家,商家按照订单信息进行发货。而取消购物的逻辑则是顾客取消订单,通知商家停止发货,退还顾客支付款项。
首先购物逻辑涉及到对订单系统、物流系统和支付系统的调用,对于顾客而言不需要自己去完成发送订单和通知商家发货,顾客只需要直接完成指定商品的支付即可,所以通过门面模式将三个系统对于购物逻辑的接口方法的调用组合在一起统一调用,调用顺序由门面负责,门面向顾客提供一个购物接口即可。取消购物的逻辑同理。
事实上,我们可以对比一下不使用和使用门面模式的区别。不使用门面模式,所有的调用由顾客自己去完成,这让顾客的购物变得更加复杂。对于顾客而言,应该更多去关注对商品的使用,而不是把精力花在如何完成购物这一行为上。一旦各个系统的接口发生变化,那么就需要在调用者的业务逻辑中去修改源代码,当业务逻辑的代码繁杂时,那么修改的成本也会比较高,如果采用门面模式,则可以更好地解决这个问题,也可以预防未来系统接口变化而引起的修改,因为门面中通常只需要编写少量的代码,所以修改也会更加快速和方便,维护成本也更低。
如果这篇文章对你有帮助,请给作者点个赞吧!