首页 > 其他分享 >系统认知篇:防腐层、门面模式及适配模式的本质

系统认知篇:防腐层、门面模式及适配模式的本质

时间:2023-04-26 09:44:42浏览次数:68  
标签:外部 适配 适配器 系统 模式 门面 子系统

作者:京东科技 倪新明

门面模式和适配器模式是代码级的设计模式,而防腐层本质是一种 防御型策略 ,在更高的层级对系统进行解耦

1 关于防腐层

Anti-Corruption Layer(ACL) 如下:

Implement a façade or adapter layer between different subsystems that don't share the same semantics . This layer translates requests that one subsystem makes to the other subsystem. Use this pattern to ensure that an application's design is not limited by dependencies on outside subsystems .

不共享语义不同子系统间实现一个门面层或适配层,该层转换一个系统到另一个子系统的请求,使用该模式确保一个应用的设计不被外部系统的依赖所限制。

2 问题背景

一个系统不可能承担所有的职能,大多数情况下都会依赖外部系统的数据或能力。这些外部系统或者遗留系统所关注的领域以及技术选型不尽相同,特别是对于一些老旧的遗留系统往往会面临是技术升级或淘汰的场景。所以,新系统与老系统间的集成往往需要适配他们的协议、数据模型、API或者某些功能特性,但是对于设计人员并不总是希望将这些方面的 “渗入” 到当前系统中。这种情况不仅仅出现在新系统和遗留系统之间,对于系统所依赖的第三方系统也同样适用,因为这些第三方系统可能存在由不同团队开发、技术选型及架构各异、领域模型不一致、可控性差等等诸多不可控因素。

上述场景在实际的业务开发中经常遇到,我们构建的系统并不是孤立的,而是会融入到公司现有的IT系统,甚至会依赖公司外部的三方服务,形式上可能基于HTTP协议的调用,也可能是内部的JSF或OPEN-API调用。这种场景下,外部系统服务提供的模型与内部系统领域上下文下的模型不能确保保持一致。如果在系统设计时不考虑隔离,而是将外部模型直接穿透到内部系统的核心域,则当模型语义产生不一致,或发生变化时,会污染自身领域。

3 解决方案

建立防腐层对不同的子系统进行隔离,该层负责转换两个子系统间的通信。通过引入防腐层,实现不同子系统间的解耦,隔离外部系统的变化对当前系统的影响,避免当前系统的设计由于外部系统的设计和技术实现方式而进行妥协

防腐层一般会包括模型转换的职能:

• 将当前系统的模型转换成外部系统的模型

• 将外部系统的响应转换成当前系统的模型

除此之外,通过在不同子系统间引入独立的 "层",可以在该层进行例如:

• 外部系统调用进行统一监控

• 对多个子系统的门面封装

• 对模型转换的适配

• 外部调用失败的降级处理

• 统一缓存机制

• .....

防腐层模式适用于:

• 如果老系统迁移至新的系统需要多个迁移阶段,但是依然要维护新系统和老系统间的集成

• 两个或更多子系统间存在不同的语义,但是依然需要相互通信

需要说明的是,如果两个系统间没有特别大的语义差异可能不太适合防腐层模式。也就是说,存在与外部系统交互的场景不一定非要使用防腐层模式,对于模型稳定、语义一致的场景,则没有必要引入额外的一层进行隔离。

4 门面模式与适配器模式

4.1 门面模式

Provide a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use .

门面模式在当前系统和外部系统之间引入了“薄薄的一层”,实现了客户端与外部复杂子系统或组件的解耦,但其并不是降低了系统的复杂性,相应的,它只是对客户端屏蔽了外部系统的复杂性,使得客户端访问子系统更加简单。

• 门面类的职能并不应该对子系统接口的返回数据模型进行封装,其只是负责简化对子系统接口的访问。

• 门面模式并不是对所有的子系统接口都进行覆盖,按需即可

• 门面类不局限于一个,例如,有多个子系统,可以按实际情况建立多个门面类

• 子系统感知不到门面类的存在,而门面类则需要感知各个子系统

• 门面类和子系统耦合,子系统接口的变更会影响到门面类的变更

4.2 适配器模式

Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces.

通过适配器模式实现两个不兼容接口的无缝集成:

适配器模式本质上适配器模式所承担的职责应该是 "不多不少",只要满足不兼容接口的适配能力即可。

适配器模式目标类和适配者类解耦,易于扩展,符合SOLID的开闭原则,同时,也提高了对已有类的复用性。但,和其他的设计模式一样,适配器模式也会引入额外的类,在一定程度上也会增加系统的复杂性,同样也会增加对代码的认知负载。

5 结语

门面模式和适配器模式是代码级的设计模式,而防腐层本质是一种防御型策略,在更高的层级对系统进行解耦。通常情况下,防腐层包含一系列的门面类和适配器类以及一些转换器类。

• 门面模式对外部系统接口进行简单封装以便更易使用

• 适配器模式负责进行内部系统与外部系统的模型兼容

• 转换器负责对扩系统的模型进行转换

标签:外部,适配,适配器,系统,模式,门面,子系统
From: https://www.cnblogs.com/jingdongkeji/p/17354710.html

相关文章

  • 单例模式细节
    提问单例模式有什么需要注意的问题回答类应该添加sealed防止继承懒汉式是线程不安全的,可以使用双锁定避免......
  • JavaScript设计模式
    JavaScript设计模式设计模式概念经过代码设计经验总结之后设计出的一种固定解决问题的方式设计模式作用代码复用保证代码可靠性将编程工程化更易被他人理解设计模式的分类(W3C平台)构造器模式,模块化模式,暴露模块模式,单例模式,中介者模式,原型模式,命令模式,外......
  • PMP-03-企业管理模式转变
    传统的垂直管理模式已经不再适应当前的发展,尤其是在互联网时代,企业需要以项目为单位的精细化管理模式转变,只有这样才能让资源得到充分的有效的利用,让项目真正的为企业和客户创造巨大的价值。......
  • 设计模式之状态模式(4)
    快过年了,想着请假提前回家,于是就不得不向领导提出申请,这个审批流是怎么实现的那?在设计模式系列之状态模式(2)中主要是通过在状态类中来对状态进行转化和维护。本文基于此实现一个简易版本的审批流程。审批流请假流程如下:说到请假,我就郁闷,就请半天假用问的那么仔细的。还有那位......
  • Docker修改容器网络模式
    docker修改容器网络模式一、创建容器时指定网终模式 dockerrun-d-p外部访问端口:容器内端口--net="网络模式"-v本机目录:容器内目录--name="容器名称"镜像名要执行的角本 dockerps查看启动的容器列表 dockerps-a查看所有的容器列表 dockerstart容器名称 启......
  • CentOS7再次探讨修改系统的启动模式(运行级别)
    1.查看当前运行级别:systemctlget-default或者runlevel或者who-r2.查看文件夹/lib/systemd/system/ll/lib/systemd/system|grepmulti-user.target ll/lib/systemd/system|grepgraphical.target ll/lib/systemd/system/default.target可以看到当前默认的runle......
  • CentOS7修改开机启动模式:命令行模式(runlevel=3)
    1.打开文件/etc/inittab: sudo/etc/inittab显示当前的runlevel:systemctlget-default设置默认的运行级别:systemcltset-defaultXX.target。XX可以是multi-user或者graphical按照提示在终端中执行命令:systemctlset-defaultmulti-user.target注意:按照inittab文件中的提......
  • lvs DR NAT模式练习
    1,重启网络/etc/init.d/networkrestart2,增加一个路由routeadd-host192.168.60.231devem1:03,增加一个真实服务器ipvsadm-a-t192.168.60.230:6006-r192.168.60.237:9092-g-w14,删除指定网关的路由routedel-netdefaultgw192.168.60.2545,删除指定主机的路......
  • chatGPT生成的简单工厂模式代码教学
    """在这个示例代码中,我们使用了简单工厂模式来创建不同的运算对象。首先,我们定义了一个Operation类作为运算类的基类,其中包含两个操作数num1和num2,以及一个get_result方法用于获取运算结果。接下来,我们定义了四个具体的运算子类Add、Subtract、Multiply和Divide,分......
  • 2.flannel的vxlan模式
    环境介绍两Pod的ip和mac信息两节点物理网卡和flannel.1的ip和mac信息原理解析我们使用k8s-1上的podcni-w4q8t去pingk8s-2上的podcni-m9l94对于podcni-w4q8t要去的目的地址10.244.1.5和自己10.244.0.3并不是同一个网段:我们需要进行路由查询需要查询Gateway10......