设计模式之门面模式
门面模式
一:门面模式概述
在现实世界中,外墙都在我们身边。操作系统就是这样一个例子 - 您没有看到计算机的所有内部工作方式,但操作系统提供了使用机器的简化界面。简而言之,门面模式旨在使事物看起来更清洁,更容易操作。
定义:为子系统中的一组接口提供统一接口。Façade定义了一个更高级别的接口,使子系统更易于使用。
门面模式只是将客户端与子系统隔离,结构图如下:
角色:
-
Facade(外观角色):在客户端可以调用它的方法,在外观角色中可以知道相关的(一个或者多个)子系统的功能和责任;在正常情况下,它将所有从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。
-
SubSystem(子系统角色):在软件系统中可以有一个或者多个子系统角色,每一个子系统可以不是一个单独的类,而是一个类的集合,它实现子系统的功能;每一个子系统都可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另外一个客户端而已。
与适配器模式一样,Facade可用于隐藏第三方库或某些遗留代码的内部工作方式。客户端需要做的就是与Facade交互,而不是它所包含的子系统.
二 :门面模式实战
某购物系统需要用户登录支付,客户端不清楚里面会调用哪些系统,它只管提供负责调用购买方法来达到购买的目的。
登录子系统:
// 登录子系统
public class Login {
public void Login(String username, String password){
// 登录相关
}
}
生成订单子系统:
//生成订单子系统
public class Order {
public void createOrder(String userName){
// 生成订单相关
}
}
支付子系统:
// 支付子系统
public class Pay {
public void payOrder(String username){
// 支付相关
System.out.println("尊敬的" + username + ",您的商品购买成功" + ";请保管好您的订单号:"
+ UUID.randomUUID().toString());
}
}
购买外观类:
// 购买外观类
public class ShopingFacade {
private Login loginHelp;
private Order orderHelp;
private Pay payHelp;
public ShopingFacade(){
this.loginHelp = new Login();
this.orderHelp = new Order();
this.payHelp = new Pay();
}
// 用户购买商品
public void shop(String userName, String password){
loginHelp.Login(userName, password);
orderHelp.createOrder(userName);
payHelp.payOrder(userName);
}
}
客户端:
public class Client {
public static void main(String[] args) {
// 购买外观类,客户端并不知道里面调用了登录,订单和支付子系统
ShopingFacade shopingFacade = new ShopingFacade();
shopingFacade.shop("tom", "123");
}
}
运行结果:
尊敬的tom,您的商品购买成功;请保管好您的订单号:438e379c-2c03-4579-b732-8bd23daf8e0b
在整个实例中,外观类对客户端屏蔽了3个子系统,减少了客户端要处理的对象,使得客户端代码变得很简单。
三:门面模式总结
优势:
使客户端和子系统隔离,客户端代码变得很简单,不需要跟多个子系统进行关联。
子系统的变化不会影响客户端的代码。
子系统直接松耦合,一个系统的修改对其他系统没有影响。
劣势:
增加新的子类系统需要可能需要修改外观类的源码,违背开闭原则。
使用场景
当要为访问一系列复杂的子系统提供一个简单入口时可以使用外观模式。
客户端程序与多个子系统之间存在很大的依赖性。引入外观类可以将子系统与客户端解耦,从而提高子系统的独立性和可移植性。
在层次化结构中,可以使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而通过外观类建立联系,降低层之间的耦合度。