SOLID原则、设计模式适用于Python语言吗
目录
正文
在阅读 clean architecture的过程中,会发现作者经常提到recompile
redeploy
,这些术语看起来都跟静态类型语言有关,比如Java、C++、C#。而在我经常使用的python语言中,是不存在这些概念的。于是,在阅读的时候就会有一个疑惑,《clean architecture》中提到的各种原则,比如SOLID,是否对动态类型语言 -- 如python -- 同样适用?
SOLID是面向对象设计的指导原则,更具适用性的应该是各种设计模式,GOF经典的Design Patterns: Elements of Reusable Object-Oriented Software 也是用C++来举例的,那么这些经典设计模式有多少是适用于动态语言如python的呢?本文记录对这些问题浅薄的思考,如果有认知错误的地方,还请大家不吝指教。
本文地址:https://www.cnblogs.com/xybaby/p/11782293.html
SOLID
SOLID是模块(module)设计的指导原则,有以下五个原则组成
- SRP(Single responsibility principle):单一职责原则,一个module只有一个原因修改
- OCP(Open/closed principle):开放-关闭原则,开放扩展,关闭修改
- LSP(Liskov substitution principle):里氏替换原则,子类型必须能够替换它们的基类型
- ISP(Interface segregation principle):接口隔离原则,你所依赖的必须是真正使用到的
- DIP(Dependency inversion principle):依赖倒置原则,依赖接口而不是实现(高层不需要知道底层的实现)
ISP
首先来看ISP,接口隔离原则,《clean architecture》的作者承认这是一个语言相关的原则
This fact could lead you to conclude that the ISP is a language issue, rather than an architecture issue.
为什么呢, ISP主要是为了解决“胖接口”导致的不必要的 recompilation and redeployment, 如下所示:
Use1对op1
的使用导致OPS的修改,导致User2 User3也要重新编译。而在动态语言中是不存在重新编译这样的问题的:
In dynamically typed languages like Ruby and Python, such declarations don’t exist in source code. Instead, they are inferred at runtime. Thus there are no source code dependencies to force recompilation and redeployment
DIP
DIP(依赖倒置原则)是SOLID的核心,OCP其实就依赖于DIP。也可以说,DIP是“clean architecture”的核心。
“clean architecture”由两部分组成:
- well-isolated components
- dependency rule
什么是”Dependency rule"呢?让低层的detail去依赖高层的policy。比如,业务逻辑(business rule)就相比数据存储(database)出于更高层,虽然逻辑上是业务逻辑要使用数据库,但为了可维护性、可扩展性,架构设计上得让database去依赖business rule,如下所示
从上图可以看出,为了达到这个目的,在静态语言中,会声明一个接口,调用的双方都依赖这个接口。如上图中的database interface
,让business rule和database都去依赖这个接口,而这个database interface和business rule在一个component,这就实现了让低层的database去依赖高层的business rule。
在静态类型语言(如Java、C++)中,其实就是利用运行时多态这个特性,使得可以在运行时 -- 而不是编译时 -- 改变软件的行为,当然为了达到这个目的,需要预先声明一个虚基类 或者接口(Java Interface)。
而在python中,本来就是运行的时候去求值,而且因为ducking type,所以无需事先声明接口或者强迫继承接口
Dependency structures in these languages(dynamic typed languages) are much simpler because dependency inversion does not require either the declaration or the inheritance of interfaces.
从静态类型语言到动态类型语言,其实是省略了很多东西
- 省略了虚函数,如template method模式
- 省略了虚基类、接口,如DIP、strategy模式
python中的依赖与依赖倒置
在python中,怎么算依赖,怎么算依赖倒置?
'''my.py''' import other class My(object): def f(self): other.act()
这一段代码中通过import
让module my
依赖于module other
,
'''my.py''' class My(object): def __init__(self, actor): self._actor = actor def