zoukankan      html  css  js  c++  java
  • 为复杂系统提供一个“综合性对外窗口”的方案——外观模式总结

    前言

    外观模式也叫门面模式,英文是 facade。这是很常见的一种设计模式,它比如 JDK 中的 Socket 接口就应用了外观模式,参考:门面模式的典型应用 Socket 和 Http(post,get)、TCP/IP 协议的关系总结

    外观模式也非常简单,它提供了一个统一的对外的高层次接口,用来访问子系统中的一群接口,也是对象的结构型模式,它符合迪米特法则——最少知道原则,类比现实,比如政府的综合性办事大厅,就非常像 facade 模式。

    闲言少叙,直接看代码,外观模式的代码非常好写,但是也不好写,简单是因为其没有特殊的组合、继承、或者抽象的地方,按照我个人理解,就是一种集中接口的思维的体现,难在需要结合业务的实际情况。

    外观模式的实现

    一个网上商城的最简单例子,在网上商城用钱买商品,也可以使用积分兑换商品,有验证系统(比如资格验证,身份验证等),支付系统,物流系统等模块,如果客户端(业务方)每次使用,都要考虑这三个接口,不仅各个子系统的 RD 维护复杂,也给业务方增加了使用负担,那么就适合使用 facade 模式,进行高层次的一个抽象。

    代码如下:Goods 代表商品类,Validate 服务,Distribute 配送服务,还有一个 payoff 支付服务,三个子系统由 facade 服务统一规划。

    public class Goods { 
        private String name;
    
        public Goods(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    ////////////////////////////////////
    public class ValidateService {
        public boolean isOk(Goods goods) {
            System.out.println("验证:" + goods.getName() + "是否有资格兑换商品");
            return true;
        }
    }
    ////////////////////////////////////
    public class PayoffService {
        public boolean payoff(Goods goods) {
            System.out.println("兑换:" + goods.getName() + " 成功");
            return true;
        }
    }
    ///////////////////////////////////
    public class DistributionService {
        public void distribution(Goods goods) {
            System.out.println("生成订单,准备配送: " + goods.getName());
        }
    }
    //////////////////////////////////
    public class FacadeService {
        private ValidateService validateService;
        private PayoffService payoffService;
        private DistributionService distributionServicel;
    
        public void setValidateService(ValidateService validateService) {
            this.validateService = validateService;
        }
    
        public void setPayoffService(PayoffService payoffService) {
            this.payoffService = payoffService;
        }
    
        public void setDistributionServicel(DistributionService distributionServicel) {
            this.distributionServicel = distributionServicel;
        }
    
        public void pay(Goods goods) {
            if (this.validateService.isOk(goods)) {
                if (this.payoffService.payoff(goods)) {
                    this.distributionServicel.distribution(goods);
                }
            }
        }
    }

    简化了客户端调用

    public class Main {
        public static void main(String[] args) {
            FacadeService facadeService = new FacadeService();
            Goods goods = new Goods("哈哈皮鞋");
            facadeService.setDistributionServicel(new DistributionService());
            facadeService.setPayoffService(new PayoffService());
            facadeService.setValidateService(new ValidateService());
            facadeService.pay(goods);
        }
    }

    效果如下:

    外观模式也可以和单例模式搭配

    比如上述案例,完全可以把子系统单例化使用,当然实际业务中,可能 Spring 全家桶更多一些,service 类直接全局配成单例的对象。

    外观模式的优点

    facade 可以让非常复杂的系统,变的简单好用,比如只提供一个对外的统一门面,屏蔽内部系统的复杂API,本质就是让系统的对外接口变少

    外观模式和中介者模式的区别

    中介者模式是双向的进行管理和约束,外观模式是单向的管理和约束。具体参考:对象关系一对多转换为一对一的方案——中介者模式总结

    欢迎关注

    dashuai的博客是终身学习践行者,大厂程序员,且专注于工作经验、学习笔记的分享和日常吐槽,包括但不限于互联网行业,附带分享一些PDF电子书,资料,帮忙内推,欢迎拍砖!

  • 相关阅读:
    datalist和repeater中radiobutton单选的问题
    SQL循环在表中增加新列
    [jQuery]使用jQuery.Validate进行客户端验证(高级篇上)——不使用微软验证控件的理由
    C# Excel 行高,列宽,合并单元格,单元格边框线,冻结 关于C#操作EXCLE常见操作比较全的
    JS弹出窗口的运用与技巧(转)
    设计模式完整备忘录
    jquery + ashx + Json 操作数据
    SQL STUFF函数 拼接字符串
    获取SQL 各字段说明,表名等有效信息
    谈谈对于企业级系统架构的理解
  • 原文地址:https://www.cnblogs.com/kubixuesheng/p/10354233.html
Copyright © 2011-2022 走看看