一、概念
1、定义:又叫门面模式,外观模式提供了一个统一的接口,用来访问子系统中一群接口的操作,这样使得子系统更容易使用,即使子系统发生变化,但只要外观不变,就不会影响到客户端代码。
2、类型:结构型
3、适用场景
- 子系统越来越复杂,增加外观模式提供简单的接口
- 构建多层系统结构,利用外观对象作为每层的入口,简化了层间调用
4、优点
- 简化调用过程,无需深入了解子系统,防止带来风险(某个功能集成到一起就行
- 减少系统的依赖,松散耦合,让内部模块更容易扩展和维护
- 帮助我们更好的划分访问的层次
- 符合迪米特法则,客户端只要和外观交互就行
5、缺点
- 增加子系统时容易引入风险
- 不符合开闭原则
6、相关设计模式
- 和适配器模式的区别
两者的差异不在于它们包装了几个类,而在于它们的意图,适配器是改变接口来符合客户的期望,外观的意图是提供给子系统一个简化的接口。外观模式可以提供多个外观,适配器也可以让多个不同的类来适配同一个接口。 - 装饰者模式:不改变接口。加入责任
- 适配器模式:将一个接口转换成另一个接口
- 外观模式:让接口更简单,应用层不要和子系统进行交互
7、UML
二、Coding
背景:积分兑换礼物
//实体 积分兑换礼物
public class PointsGift {
private String name;
public PointsGift(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
//子系统一:验证是否满足兑换资格
public class QualifyService {
public boolean isAvailable(PointsGift pointsGift) {
System.out.println("校验" + pointsGift.getName() + " 积分资格通过,库存通过");
return true;
}
}
//子系统二:积分支付子系统
public class PointsPaymentService {
public boolean pay(PointsGift pointsGift) {
//扣减积分逻辑
System.out.println("支付" + pointsGift.getName() + " 积分成功");
return true;
}
}
//子系统三:物流子系统
public class ShippingService {
public String shipGift(PointsGift pointsGift) {
//物流系统对接逻辑
System.out.println(pointsGift.getName()+"进入物流系统");
String shippingOrderNo = "6666666";
return shippingOrderNo;
}
}
//客户端只关心礼物兑换逻辑,不需要知道这么多子系统
//外观类提供礼物兑换服务
//对外通过外观类和应用层去交互,应用层不需要关注子服务,很好的体现了迪米特法则
public class GiftExchangeService {
private QualifyService qualifyService = new QualifyService();
private PointsPaymentService pointsPaymentService = new PointsPaymentService();
private ShippingService shippingService = new ShippingService();
public void giftExchange(PointsGift pointsGift) {
if (qualifyService.isAvailable(pointsGift)) {
//资格校验通过
if (pointsPaymentService.pay(pointsGift)) {
//如果支付成功
String shippingOrderNo = shippingService.shipGift(pointsGift);
System.out.println("物流系统下单成功,订单号是:"+shippingOrderNo);
}
}
}
}
public class Test {
public static void main(String[] args) {
PointsGift pointsGift = new PointsGift("T恤");
GiftExchangeService giftExchangeService = new GiftExchangeService();
giftExchangeService.giftExchange(pointsGift);
}
}