1、概念
外观模式是外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用,属于对象结构型模式。
2、模式结构
- Facade(Controller): 外观角色,客户端通过操作外观角色从而达到控制子系统角色的目的。对于客户端来说,外观角色好比一道屏障,对客户端屏蔽了子系统的具体实现
- SubSystem(Service): 子系统角色。表示一个系统的子系统或模块
3、使用场景
- 一个复杂子系统提供一个简单接口时可以使用外观模式
- 客户程序与多个子系统之间存在很大的依赖性
- 一个难以维护和扩展的系统,但又包含非常重要的功能,为其开发一个外观类,以便新系统与其交互
4、优缺点
优点:
- 客户代码将变得很简单,与之关联的对象也很少
- 实现了子系统与客户之间的松耦合关系
- 子系统的修改对其他子系统没有任何影响,而且子系统内部变化也不会影响到外观对象
- 提供了一个访问子系统的统一入口,并不影响用户直接使用子系统类
缺点:
- 客户访问子系统类做太多的限制则减少了可变性和灵活性
- 违背了开闭原则,不引入抽象外观类的情况下,增加新的子系统可能需要修改外观类或客户端的源代码
5、实例
给业务端提供一个API,业务端只需要根据这个API获取相关信息,而不需要知道各子系统的处理逻辑,例如根据用户获取相关的订单信息。定义UserService处理类,处理User的相关逻辑
public class UserService {
public boolean isRealUser(long userId){
// 用户逻辑判断
return false;
}
}
定义OrderService处理类,处理Order的相关逻辑
public class OrderService {
public List<Order> getOrderList(long userId, int page, int pageSize) {
// 订单逻辑
return new ArrayList<>();
}
}
定义ProductService处理类,处理Product的相关逻辑
public class ProductService {
public List<Product> getProductList(List<Integer> productIdList){
// 产品逻辑
return new ArrayList<>();
}
}
定义API处理类,负责跟业务端打交道
public class ApiController {
private UserService userService;
private ProductService productService;
private OrderService orderService;
public ApiController() {
userService = new UserService();
productService = new ProductService();
orderService = new OrderService();
}
public List<Order> getOrderList(long userId, int page, int pageSize) {
if (!userService.isRealUser(userId)) return null;
List<Order> list = orderService.getOrderList(userId, page, pageSize);
if (list == null || list.size() == 0) return null;
for (Order order : list) {
order.setProducts(productService.getProductList(order.getProducts().stream().map(Product::getProductId)).collect(Collectors.toList()));
}
return list;
}
}
业务端调用方式
ApiController apiController = new ApiController();
apiController.getOrderList(10, 1, 10);