外观模式定义
外观模式(Facade Pattern)隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式,它向现有的系统添加一个接口,来隐藏系统的复杂性。
具体例子
我们系统里面有很多服务,这些服务很复杂,我们想要屏蔽复杂的实现,提供一个统一的入口给开发人员调用,这些接口包括鉴权,单点登录,用户 信息,保存订单,查询订单等,如果我们不使用外观模式来统一入口的话,那么其他开发人员来调用这些接口时,首先需要注入各个模块,然后再调用 接口,这样就会产生很多冗余的代码,并且容易出错。
代码语言:javascript复制@AllArgsConstructor
public class Client2 {
private AuthService authService;
private UserService userService;
private SsoService ssoService;
private BusinessService businessService;
public void doIt(){
String token = "";
Result auth = authService.auth(token);
Result userInfo = userService.userInfo(token);
Result ssoLogin = ssoService.ssoLogin(token);
Result query = businessService.query("123");
Result save = businessService.save(new Order());
}
}
现在使用外观外观模式来改造。
Facade
:SysFacade
是请求的统一入口,并调用相应的子系统接口。
SubSystem
:子系统,子系统就是具体的实现接口,AuthService
,BusinessService
,SsoService
,UserService
。
AuthService
public class AuthService {
public Result auth(String token){
return new Result(200,"授权成功",null);
}
}
BusinessService
public class BusinessService {
public Result save(Order order){
return new Result(200,"保存成功",null);
}
public Result query(String id){
Order order = new Order();
return new Result(200,"获取成功",order);
}
}
SsoService
public class SsoService {
public Result ssoLogin(String token){
return new Result(200,"单点登录","url");
}
}
UserService
public class UserService {
public Result userInfo(String token){
return new Result(200,"获取用户信息成功","userInfo");
}
}
定义外观角色(统一入口) SysFacade
public class SysFacade {
private final AuthService authService;
private final SsoService ssoService;
private final UserService userService;
private final BusinessService businessService;
public SysFacade(){
this.authService = new AuthService();
this.ssoService = new SsoService();
this.userService = new UserService();
this.businessService = new BusinessService();
}
public Result auth(String token){
return authService.auth(token);
}
public Result ssoLogin(String token){
return ssoService.ssoLogin(token);
}
public Result userInfo(String token){
return userService.userInfo(token);
}
public Result saveOrder(Order order){
return businessService.save(order);
}
public Result queryById(String id){
return businessService.query(id);
}
}
Client
调用
public class Client {
public static void main(String[] args) {
SysFacade facade = new SysFacade();
Result auth = facade.auth("token");
Result ssoLogin = facade.ssoLogin("token");
Result userInfo = facade.userInfo("token");
facade.saveOrder(new Order());
facade.queryById("123456");
}
}
至此,开发人员只需要使用外观角色SysFacade便可调用对应的接口。
其实外观模式我们在开发中是经常使用的,只是有些时候我们没有抽象出这个概念来而已,比如我们编写了一个Controller,里面调用了很多个Service ,然后Service又调用了很多模块,不过最终我们只调用了Controller的接口,里面的其他接口实现全部屏蔽了,所以MVC本身就是使用 外观模式的思想。
优点
我们使用外观模式后,可以很好的解耦系统,因为只提供了一个统一入口,对于里面的实现全部屏蔽了,所以具体实现变化的时候只需要修改 具体实现类。 提升安全性:因为具体逻辑是不可见的,所以会避免一些错误。
缺点
违背了开闭原则。