外观模式
定义:
又叫门面模式,提供了一个统一的接口,用来访问子系统中的一群接口
外观模式定义了一个高层接口,让子系统更容易使用
类型:
结构型
适用场景:
子系统越来越复杂,增加外观模式提供简单调用接口;
构建多层系统结构,利用外观对象作为每层的入口,简化层间调用
优点:
简化了调用过程,无需了解深入子系统,防止带来风险;
减少系统依赖、松散耦合;
更好的划分访问层次;
符合迪米特法则,即最少知道原则
缺点:
增加子系统、扩展子系统行为容易引用风险;
不符合开闭原则
外观模式相关设计模式
- 中介者模式
关注子系统内部间的交互 - 单例模式
外观对象使用单例模式 - 抽象工厂模式
外观类通过抽象工厂获取子系统的实例,子系统可在内部对外观类进行屏蔽
具体实现:
礼物兑换案例
应用层Test只和外观类GiftExchangeService通信,不与子系统交互
增加子系统需要修改外观类,不符合开闭原则
如外观类变动频繁,可使用抽象外观类
@AllArgsConstructor
@Getter
public class PointsGift {
private String 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() + "进入物流系统");
return "订单号: 335213552";
}
}
外观类:
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("罗技无线鼠标");
GiftExchangeService giftExchangeService = new GiftExchangeService();
giftExchangeService.giftExchange(pointsGift);
}
}
输出:
校验罗技无线鼠标积分资格通过
支付罗技无线鼠标积分成功
罗技无线鼠标进入物流系统
积分下单成功!订单号: 335213552
具体应用:
1、org.springframework.jdbc.support.JdbcUtils
对JDBC接口进行封装
....
public static void closeConnection(@Nullable Connection con) {
if (con != null) {
try {
con.close();
}
catch (SQLException ex) {
logger.debug("Could not close JDBC Connection", ex);
}
catch (Throwable ex) {
// We don't trust the JDBC driver: It might throw RuntimeException or Error.
logger.debug("Unexpected exception on closing JDBC Connection", ex);
}
}
}
...
2、org.apache.ibatis.session.Configuration
public MetaObject newMetaObject(Object object) {
return MetaObject.forObject(object, objectFactory, objectWrapperFactory, reflectorFactory);
}
public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
return parameterHandler;
}
tomcat
3、org.apache.catalina.connector.RequestFacade
HttpServletRequest的外观类
public class RequestFacade implements HttpServletRequest {
}
4、org.apache.catalina.connector.Request
public class Request implements HttpServletRequest{
...
protected RequestFacade facade = null;
/**
* @return the <code>ServletRequest</code> for which this object
* is the facade. This method must be implemented by a subclass.
*/
public HttpServletRequest getRequest() {
if (facade == null) {
facade = new RequestFacade(this);
}
if (applicationRequest == null) {
applicationRequest = facade;
}
return applicationRequest;
}
}
5、ResponseFacade、Response、StatementFacade、StandardWrapperFacade等