在现实世界中,外墙都在咱们身边。操做系统就是这样一个例子 - 您没有看到计算机的全部内部工做方式,但操做系统提供了使用机器的简化界面。简而言之,门面模式旨在使事物看起来更清洁,更容易操做。java
定义:为子系统中的一组接口提供统一接口。Façade定义了一个更高级别的接口,使子系统更易于使用。dom
门面模式只是将客户端与子系统隔离,结构图以下:this
角色:spa
**Facade(外观角色):**在客户端能够调用它的方法,在外观角色中能够知道相关的(一个或者多个)子系统的功能和责任;在正常状况下,它将全部从客户端发来的请求委派到相应的子系统去,传递给相应的子系统对象处理。操作系统
SubSystem(子系统角色):在软件系统中能够有一个或者多个子系统角色,每个子系统能够不是一个单独的类,而是一个类的集合,它实现子系统的功能;每个子系统均可以被客户端直接调用,或者被外观角色调用,它处理由外观类传过来的请求;子系统并不知道外观的存在,对于子系统而言,外观角色仅仅是另一个客户端而已。3d
与适配器模式同样,Facade可用于隐藏第三方库或某些遗留代码的内部工做方式。客户端须要作的就是与Facade交互,而不是它所包含的子系统.
code
某购物系统须要用户登陆支付,客户端不清楚里面会调用哪些系统,它只管提供负责调用购买方法来达到购买的目的。cdn
登陆子系统:对象
// 登陆子系统
public class Login {
public void Login(String username, String password){
// 登陆相关
}
}
复制代码
生成订单子系统:blog
//生成订单子系统
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个子系统,减小了客户端要处理的对象,使得客户端代码变得很简单。
优点:
使客户端和子系统隔离,客户端代码变得很简单,不须要跟多个子系统进行关联。
子系统的变化不会影响客户端的代码。
子系统直接松耦合,一个系统的修改对其余系统没有影响。
劣势:
增长新的子类系统须要可能须要修改外观类的源码,违背开闭原则。
当要为访问一系列复杂的子系统提供一个简单入口时可使用外观模式。
客户端程序与多个子系统之间存在很大的依赖性。引入外观类能够将子系统与客户端解耦,从而提升子系统的独立性和可移植性。
在层次化结构中,可使用外观模式定义系统中每一层的入口,层与层之间不直接产生联系,而经过外观类创建联系,下降层之间的耦合度。