外观模式(门面模式):
定义:提供了一个统一的接口,用来访问子系统中的一群接口:
外观模式定义了一个高层接口,让子系统更容易使用
类型:
结构性
使用场景:
- 子系统越来越复杂,增加外观模式提供简单调用接口
- 构建多层系统结构,利用外观对象作为每层的入口,简化层之间的调用
优点:
- 简化调用过程,无须深入了解子系统,防止带来风险
- 减少系统依赖,松散耦合
- 更好的划分此层
- 符合迪米特法则,即最少知道系统
缺点:
- 增加子系统,扩展子系统行为容易引入风险
- 不符合开闭原则
例子:
场景:
有个网站允许用户用自己的积分来兑换商店内礼物,兑换需要经过校验积分,支付积分,生成订单的过程,单对调用兑换积分的接口来说不用关心里面的三个过程,只需关心调用兑换积分的接口;
- 新建积分兑换礼物实体类:
package com.tangbaobao.design.pattern.cretional.structral.faced;
/**
* @author tangxuejun
* @version 2019-04-21 16:33
*/
public class PointsGift {
private String name;
public PointsGift(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "PointsGift{" +
"name='" + name + '\'' +
'}';
}
}
- 积分支付校验类:
package com.tangbaobao.design.pattern.cretional.structral.faced;
/**
* @author tangxuejun
* @version 2019-04-21 16:33
*/
public class QualifyService {
public boolean isAvailable(PointsGift pointsGift) {
System.out.println("校验名称" + pointsGift.getName() + "积分资格通过,库存通过");
return true;
}
}
- 积分支付和兑换服务
package com.tangbaobao.design.pattern.cretional.structral.faced;
/**
* @author tangxuejun
* @version 2019-04-21 16:36
*/
public class PointPaymentService {
public boolean isPaySuccess(PointsGift pointsGift) {
System.out.println("支付" + pointsGift.getName() + "成功");
return true;
}
}
- 生成订单
package com.tangbaobao.design.pattern.cretional.structral.faced;
/**
* @author tangxuejun
* @version 2019-04-21 16:38
*/
public class ShippingService {
public String shipGift(PointsGift pointsGift) {
System.out.println(pointsGift.getName() + "进入物流系统");
return "9999";
}
}
- 聚合以上服务,来对外提供接口:
package com.tangbaobao.design.pattern.cretional.structral.faced;
/**
* @author tangxuejun
* @version 2019-04-21 17:24
*/
public class GiftExchangeService {
private final QualifyService qualifyService = new QualifyService();
private final PointPaymentService pointPaymentService = new PointPaymentService();
private final ShippingService shippingService = new ShippingService();
public void giftExchange(PointsGift pointsGift) {
if (qualifyService.isAvailable(pointsGift)) {
System.out.println("校验通过");
if (pointPaymentService.isPaySuccess(pointsGift)) {
String shipGift = shippingService.shipGift(pointsGift);
System.out.println("物流系统下单成功" + shipGift);
}
}
}
}
上述生成的UML图:
可见GiftExchangeService服务作为门面接口,屏蔽了外界和内部其他三个接口的访问,很好的符合迪米特法则。