设计模式-门面

定义:
结构型门面模式(Facade Pattern)又叫外观模式,指提供了一个统一的接口用来访问子系统中的一群接口:定义一个高层接口,让子系统更容易使用,生活中常见的例子:前台接待员,包工头 ...

门面与代理:
门面模式重点在于封装,静态代理重点在于增强,可以说不做增强的静态代理就是门面模式

使用场景:
1.随着系统越来越复杂,可增加门面提供简单接口
2.构建多层系统结构,利用门面对象作为每层的入口简化层间调用
优点:
1.简化调用过程,无需深入了解子系统,以防给子系统带来风险
2.对于客户端而言减少系统依赖,松散耦合
3.更好的划分访问层次,提高安全性,例如MVC
4.遵循迪米特法则,即最少知道原则

缺点:
1.当增加子系统和扩展子系统行为时(修改),可能带来未知的风险
2.不符合开闭原则
3.某些情况下可能违背单一职责原则,当成为一个万能类时维护起来就很困难

示例:

/**
 * 假设用积分下单,流程:
 * 购买礼品->调启支付系统->调积分系统->调物流系统
 */
public class GiftInfo {
    private String name;
    public GiftInfo(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
}
// 支付
public class PaymentService {
    private final static Logger logger = Logger.getLogger(PaymentService.class);
    public boolean pay(GiftInfo gift){
        logger.info("扣减" + gift.getName() + "积分成功");
        return true;
    }
}
// 积分
public class QualifyService {
    private final static Logger logger = Logger.getLogger(PaymentService.class);
    public boolean isAvailable(GiftInfo gift){
        logger.info("验证" + gift.getName() + "积分通过,库存通过");
        return true;
    }
}
// 物流
public class ShippingService {
    private final static Logger logger = Logger.getLogger(PaymentService.class);
    public String delivery(GiftInfo gift){
        logger.info(gift.getName() + "物流运送中 ..");
        // 返回物流单号
        return "5788698";
    }
}
/**
 * 门面
 */
public class FacedeService {
    private final static Logger logger = Logger.getLogger(FacedeService.class);
    private PaymentService pay = new PaymentService();
    private QualifyService qualify = new QualifyService();
    private ShippingService shipping = new ShippingService();
    public void exchange(GiftInfo gift){
        if(pay.pay(gift)){
            if(qualify.isAvailable(gift)){
                String ShippingNum = shipping.delivery(gift);
                logger.info("下单成功,物流单号是:" + ShippingNum);
            }
        }
    }
}
// 模拟客户端
public class MainExcute {
    private final static Logger logger = Logger.getLogger(MainExcute.class);
    public static void main(String[] args) {
        // 未使用门面之前
        GiftInfo gift = new GiftInfo("《Spring5 核心原理》");
        PaymentService pay = new PaymentService();
        QualifyService qualify = new QualifyService();
        ShippingService shipping = new ShippingService();
        if(pay.pay(gift)){
            if(qualify.isAvailable(gift)){
                String ShippingNum = shipping.delivery(gift);
                logger.info("下单成功,物流单号是:" + ShippingNum);
            }
        }
        // 使用门面之后,客户端只需要调用一个接口
        FacedeService facede = new FacedeService();
        facede.exchange(gift);
        /**
         * 门面模式在源码中的应用
         * tomcat中也用的比较多,例:RequestFacede,ResponseFacede 类中
         */
    }
}

类图:

image.png

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容