不要在主进程里去实现细节,方法的使用都应该通过抽象接口,主进程只能关注结果而不是实现的路径
最近在对项目中的某一模块进行重构和功能的拓展。一直没想到好方法。
简单理解为: R项目 调用了 E项目的打印接口,但是E项目需要对R传来对数据传输对象DTO进行二次处理,甚至夹杂很多R项目的业务逻辑(去调用R项目的接口),经过多个迭代以后,R项目和E项目的接口对接人已经成为了相亲相爱一家人👨👩👧👧。
Team leader 一语点醒:“依赖倒置”
突然感觉到自己以前对于OOP的各种概念还处于浮于表面的理解。实战中还用不出来。
举个栗子🌰
传统:
开始的电脑,各组件(内存、显卡等)根据某个厂家的产品直接焊接集成到一起。
DIP:
各组件都定义标准接口,主板上预留标准接口,各厂家按标准接口来生产。
这样就很容易更换不同厂家的产品。
传统系统:高层模块依赖低层模块。
DIP第一层境界:低层模块依赖高层模块。
DIP第二层境界:无论高层模块或低层模块实现的细节,都依赖于独立出来的抽象层。
依赖倒置原则应用广泛,在面向对象程序框架设计中(是核心原则)、架构系统中、在社会活动构建组织等方面,都发挥重要作用。
DIP在面向对象程序设计中,面向接口编程是基础,而核心是"依赖倒置"。
一般来说,系统中存在违反DIP的地方,很可能就是我们需要优化的地方。
好的回到项目开始思考:
1. E项目不应该关注R到业务逻辑
2. R项目只应该调用最通用的E项目接口,并且进行单项数据流,不应该出现反复横跳
基于现有的问题,首先为什么E会关注R的业务?R的DTO处理不够干净,九转大肠,接口对接人还需要干一些脏活累活。
从代码层面来说,E应该只定义接口的规范,具体的实现让R来做,比如打印类的定义可以直接继承自R项目的DTO,这样不会因为业务的频繁变动而导致对接人的工作量增加。
其次,抽离最通用的业务,即打印的逻辑,打印函数不关心你的DTO如何定义,只负责获取到并且DFS解析出,根据某具有唯一性的key来进行模板的数据替换。 同样的,替换模板的生成也不应该关注R的业务,根据R定义的DTO/Entity 来动态生成的对应的XML。
动态生成XML已经实现了,基本上思路就是根据Entity及其guid,生成对应的节点,设置唯一属性GUID方便后期替换数据。
XML Documents and Data | Microsoft Learn
那么具体实现到何种境界,还需要一段时间的思考🤔
此blog 待补充。。。
2023/3/4 知识点的补充
具体的code sample,可以尝试用在工作项目里面。
首先是 过分依赖的代码 ,Agency 过分依赖 class的具体实现
使用依赖倒置之后的代码,创建 抽象接口
看 接口不需要依赖 具体的类,而是 依赖其抽象类。
人话:不要宝马class 奔驰class 只需依赖 CarManufactory class
2023/3/5
需要阅读更多的代码例子,才能用到实际工作中。
高层:调用方 R
低层:被调用方 E
思考:打印的时候,E会调R的接口,这时候 E其实是高层。 R调用E打印方法的时候,E又是作为低层的。
所以这个项目间的优化不能轻易判断,得找到接口的调用方及其时机,单独进行抽象。
c# 中的案例,多个品种的手机继承自 AbstractPhone
where 进行T类型约束
重点!!!!:这个等价于
为什么可以这样?
重点:任何父类出现的地方,都可以使用子类代替 。 这叫做面向抽象编程
so:依赖倒置 可以 当作 面向抽象编程
使用方法 PlatT(),通过类型推断出
这样做之后的好处:
可能存在的局限性:
特别内容指的是,子类特有的的属性 或者 方法
so: