在《不过时的经典层架构》里,有朋友留言关于Manager和Engine的概念,虽然朋友留言把概念解释清楚了。为了避免其他人有同样的疑问,这里我还是再解释一下。
以上是经典的四层架构,在这个架构中,Manager和Engine(引擎)都是业务逻辑层的概念。Manager中文就是管理者,就是把行为管理起来。Engine是行为本身。咱们超出业务逻辑层,针对这个概念本身来看,什么是引擎行为呢?咱们很多朋友听说过搜索引擎、计算引擎吧。为什么搜索引擎称之为引擎呢?因为它一般不是独立使用的,一般是嵌入到网站上,作为网站上的一个行为,这个行为是对信息进行组织处理后,为用户提供检索服务,并将相关信息展示给用户。这个行为最重要的特点是整套一起使用。如果整套都是一起使用,易变性低,可以作为基础操作,这就可以称之引擎。Manager管理者这个角色与Engine引擎最大的不同就是易变性上,它组织了一个或者多个行为,如果这些行为都是一起使用,序列也不变,那也可以叫一个引擎。就像搜索引擎里综合信息处理,提供检索服务一样。但是序列,也就是行为的组织方式易变,那就需要一个管理者来组织。下面会有例子说明为什么一定要清楚这个。
下面来说一下今天的正题,开闭架构。
开放架构
在开放架构中,无论组件在哪一层,都可以随意进行调用。这些调用关系包含向上层调用,向下层调用,平行调用。开放架构提供了无止境的灵活性,但是牺牲了封装性,引入了耦合。
比如向上层调用:在四层架构中,业务层调用客户端。一旦UI变了,业务层就也得跟着变了。
但是实际中,那么傻的事情是很少发生的。但是,实际上有时候我们非常想,我暴露一个对外接口,这个接口作用就是调用一下数据库做个处理。我何苦这么麻烦,先封装一个XXManager,XXManager调用XXEngine,XXEngine还要调用XXAccess。其实这些里面只是直接调用了下一层,其他什么也没有做,直接调用数据库多省事啊。这里面就涉及到易变性封装的问题,客户端需求变了,要动很底层。
所以,当然,开放架构是目前不推荐的架构形式。
封闭架构
在封闭架构中,不允许向上层调用和同级调用,只允许向下调用。这样就牺牲了灵活性,但是封装了易变性,同时促进解耦。也是一般比较推荐的架构。
但在咱们实际的项目中,会有一些同级调用的冲动。就是这种冲动会让代码很难维护。比如有段逻辑A,是Manager层的。另外来了一个需求B,正好可以复用这部分代码,同时增加一些其他逻辑。那本着代码复用,减少重复代码的原则,我应该直接调用A啊。为了不打乱层级,我把这段公共代码抽到下一层Engine层。那这段逻辑也要调用Engine层啊,不又是同级调用了吗?按照我的经验,一般这种情况是习惯于Engine层很薄导致的,概念解释说了引擎可以是一个大组件。可以检查一下Engine同级调用的地方是不是可以直接调用Access不会引起很多重复代码。如果不行,那说明咱们的业务逻辑过于复杂,四层不够,架构设计少了一层。
半开半闭架构
在半开半闭架构中,允许向下多层调用。我记得十几年前,我特别喜欢写数据库存储过程,代码端可干净了。因为逻辑全在数据库那里,这个时候开放架构是很合适的,因为一旦有改动,核心改动点在存储过程,上面都要跟着变,当然上层越少越好了。但是现在大型项目都不推荐使用存储过程了,最重要的一点就是易变性。
这种调用也是封装性和灵活性的妥协,也是要避免的。
封闭架构中规则的放松
封闭架构过于严格,有些代码编写就会殊为不易。所以它有两个明确的放松规则的例外:
调用工具
像日志和监控埋点等工具,其他层均可调用。
弱引用
比如在两个Manager之间使用了队列作为调用方式,因为是弱引用,是允许同级调用的。