白话设计模式之外观模式

2022-07-26 17:03:14 浏览数 (1)

外观模式定义

外观模式(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());
    }
}

现在使用外观外观模式来改造。 FacadeSysFacade是请求的统一入口,并调用相应的子系统接口。 SubSystem:子系统,子系统就是具体的实现接口,AuthServiceBusinessServiceSsoServiceUserService

AuthService

代码语言:javascript复制
public class AuthService {
    public Result auth(String token){
        return new Result(200,"授权成功",null);
    }
}

BusinessService

代码语言:javascript复制
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

代码语言:javascript复制
public class SsoService {
    public Result ssoLogin(String token){
        return new Result(200,"单点登录","url");
    }
}

UserService

代码语言:javascript复制
public class UserService {
    public Result userInfo(String token){
        return new Result(200,"获取用户信息成功","userInfo");
    }
}

定义外观角色(统一入口) SysFacade

代码语言:javascript复制
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调用

代码语言:javascript复制
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本身就是使用 外观模式的思想。

优点

我们使用外观模式后,可以很好的解耦系统,因为只提供了一个统一入口,对于里面的实现全部屏蔽了,所以具体实现变化的时候只需要修改 具体实现类。 提升安全性:因为具体逻辑是不可见的,所以会避免一些错误。

缺点

违背了开闭原则。

0 人点赞