一.定义
提供一个统一的接口,用来访问子系统的一群接口(也称门面模式)
简单来说:有一个统一的对外口径,它的实现可能调用了很多子系统的接口
二.适用场景
- 子系统越来越复杂,增加外观模式提供简单调用接口
- 构建多层系统结构,利用外观对象作为每层的入口,简化层间调用
三.优缺点
1.优点
- 简化调用过程,无需了解、深入子系统,防止带来风险
- 减少系统依赖、松散耦合
- 更好的划分访问层次
2.缺点
- 增加子系统、扩展子系统行为容易引入风险
四.角色
- 1.外观对象(可能包含接口和具体实现类)
- 2.子系统服务对象
五.实例
交易系统中一个取消订单的接口,它可能涉及很多操作,但客户端只需要调用取消订单即可,其他细节,它不需要关心
1.订单数据实体
package com.shixinke.practise.design.pattern.content.structural.facade;
import java.math.BigDecimal;
/**
* 订单实体
* @author shixinke
*/
public class Order {
/**
* 订单ID
*/
private Long orderId;
/**
* 用户
*/
private Long userId;
/**
* 支付方式
*/
private Short payment;
/**
* 金额
*/
private BigDecimal amount;
/**
* 订单状态(这里为了简单,不将物流状态/支付状态等分开)
*/
private Short status;
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Short getPayment() {
return payment;
}
public void setPayment(Short payment) {
this.payment = payment;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public Short getStatus() {
return status;
}
public void setStatus(Short status) {
this.status = status;
}
/*
* 订单状态定义
*/
public enum Status {
UNPAID(Short.valueOf("1")),
PAID(Short.valueOf("2"));
private Short value;
Status(Short value) {
this.value = value;
}
public Short getValue() {
return value;
}
}
}
2.接口响应实体
/**
* 接口响应类
* @author shixinke
*/
public class ResponseDTO<T> {
/**
* 状态码
*/
private Integer code;
/**
* 提示信息
*/
private String message;
/**
* 是否成功
*/
private boolean success;
/**
* 数据体
*/
private T data;
public ResponseDTO(Integer code, String message, boolean success, T data) {
this.code = code;
this.message = message;
this.success = success;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public static ResponseDTO error(int code, String message) {
return new ResponseDTO(code, message, false, null);
}
public static <T> ResponseDTO success(T data) {
return new ResponseDTO(200, "success", true, data);
}
}
3.订单子服务
(1)订单服务接口
/**
* 订单服务接口
* @author shixinke
*/
public interface OrderService {
/**
* 获取订单信息
* @param orderId
* @return
*/
Order getOrder(Long orderId);
/**
* 取消订单
* @param orderId
* @return
*/
boolean cancelOrder(Long orderId);
}
(2)订单服务实现
/**
* 订单服务(实现)
* @author shixinke
*/
public class OrderServiceImpl implements OrderService {
/**
* 获取订单
* @param orderId
* @return
*/
public Order getOrder(Long orderId) {
/**
* 查询操作
*/
Order order = new Order();
return order;
}
/**
* 取消订单操作
* @param orderId
* @return
*/
public boolean cancelOrder(Long orderId) {
System.out.println("修改订单状态,将订单修改为已取消");
return true;
}
}
4.支付子系统
(1)支付服务接口
/**
* 支付服务
* @author shixinke
*/
public interface PaymentService {
/**
* 退款
* @param userId 用户
* @param amount 金额
* @return
*/
boolean refund(Long userId, BigDecimal amount);
}
(2)支付服务实现
/**
* 支付服务
* @author shixinke
*/
public class PaymentServiceImpl implements PaymentService {
/**
* 退款
* @param userId 用户
* @param amount 金额
* @return
*/
public boolean refund(Long userId, BigDecimal amount) {
System.out.println("发起退款操作");
return true;
}
}
5.订单对外服务(外观类)
(1)外观类服务接口
/**
* 订单对外接口
* @author shixinke
*/
public interface OrderFacade {
/**
* 取消订单
* @param orderId
* @param userId
* @return
*/
ResponseDTO cancelOrder(Long orderId, Long userId);
}
(2)外观类服务实现
/**
* 订单(实现)
*/
public class OrderFacadeImpl implements OrderFacade {
/**
* 取消订单
* @param orderId
* @param userId
* @return
*/
public ResponseDTO cancelOrder(Long orderId, Long userId) {
/**
* 1.获取订单信息
*/
OrderService orderService = new OrderServiceImpl();
Order order = orderService.getOrder(orderId);
if (order == null) {
return ResponseDTO.error(404, "订单不存在");
}
/**
* 订单所属用户判断(查看是否有权限)
*/
if (!order.getUserId().equals(userId)) {
return ResponseDTO.error(401, "订单不存在");
}
/**
* 订单状态判断(哪些状态不能取消)
*/
/**
* 2.取消订单操作
*/
boolean result = orderService.cancelOrder(orderId);
if (!result) {
return ResponseDTO.error(500, "订单取消失败");
}
/**
* 退款操作(可以是通过异步MQ,或同步操作方法,记录日志等)
*/
boolean needRefund = true; //哪些状态需要退款
if (needRefund) {
PaymentService paymentService = new PaymentServiceImpl();
boolean refundResult = paymentService.refund(userId, order.getAmount());
if (!refundResult) {
//退款失败的操作,回滚或者其他
}
}
return ResponseDTO.success(null);
}
}
以上类的UML关系图: