hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

SOLID准绳、设想形式适用于Python言语吗

2019-11-18杂谈搜奇网34°c
A+ A-

在浏览 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 f(self):
        self._actor.act()

那末在这里,my和other有依靠关联吗?没有的,这里压根就没有涌现过other。因为动态范例加上ducking type,基础无需显式的接口定义,只需遵照相干的协定(左券)即可。而这个左券,没办法经由历程代码强行束缚,挪用者须要什么样的接口,被挪用者应当具有什么样的行动,都只能经由历程文档(或许单元测试)来形貌。

为了表达左券,上述代码应当加上docstring

'''my.py'''
class My(object):
    def __init__(self, actor):
        '''Param: actor,该对象须要具有吸收0个参数的act要领
        '''
        self._actor = actor

    def f(self):
        self._actor.act()

python中大批运用相似的协定,如context management, iterator protocol。虽然很轻易,同时也对程序员有更高请求,因为最少得有靠谱的docstring。假如须要强加束缚,那是是能够斟酌运用abc的。

设想形式

起首声明的是,在本文中提到的设想形式,平常指Design Patterns: Elements of Reusable Object-Oriented Software 这本书中所形貌的典范设想形式。

很早之前看过一种说法,“++设想形式是对静态言语缺点的填补”++,当时没经思索就全盘接受了,窃以为这就是真谛。近来才真正思索这个题目,发明这类说法存在私见与不周全。

起首抛出一个题目:设想形式是言语相干吗(language-specific)?是某种范例的编程言语须要设想形式,而别的一些编程言语就不须要?或许说,差别的编程言语须要的设想形式是不一样的?

什么是设想形式呢,《Design Patterns》中形貌为,针对软件设想中某一类特定题目的简朴且幽美的处置惩罚方案。

Describes simple and elegant solutions to specific problems in object-oriented software design

也就是说,设想形式是处置惩罚某类特定题目的套路,或许说要领论。套路是针对某个题目,经由理论或实践考证的、卓有成效的要领与步骤。没有要领论也能处置惩罚题目,能够就须要去大批的尝试、试错,获得一种处置惩罚办法(大几率也不是最优解),这个求解的历程耗时且低效。因而能够说,要领论(形式)加快了题目求解的历程。

比方,程序员天天都很大批的事变要做:要开会、要写代码、要处置惩罚bug、要本身充电。怎样部署呢?能够本身思索这个题目就得焦头烂额,然则已经有成熟的要领论 --艾森豪威尔矩阵-- 可供运用了啊。

我们常说,站在伟人的肩膀上,套路、要领论就是伟人的肩膀。

设想形式一样云云。

设想形式与动态言语

《Design Patterns》这本书,写于1994年,作者提到写这本数的目的,就是将这些卓有成效的履历纪录下来。前面提到,设想形式是针对一类题目的处置惩罚方案,那末在引见一种设想形式的时刻,就一定会涉及到以下内容(包含但不限于):

  • 要处置惩罚的题目是什么
  • 处置惩罚方案是什么模样的
  • 处置惩罚方案的缺点与实用场景
  • 处置惩罚方案的细致步骤
  • 针对同一个题目,有无其他处置惩罚方案,各自的好坏

固然,起首得给这个形式取一个恰到好处的名字,定名的重要性不容质疑。最少保证程序员之间在沟通的时刻所表达的是同一个题目,不论这个沟通是peer to peer,照样经由历程代码。名字(术语、定义)也就减轻了沟通的本钱。

在《Design Patterns》写成的两年后,即1996年,Peter Norvig就做了一个分享 “Design Patterns in Dynamic Programming”, 指出因为动态言语存在更少的言语层面的限定,GOF中的大多数设想形式在Lisp或许Dylan有更简朴的完成,有的以至简朴到基础无需注重

16 of 23 patterns have qualitatively simpler implementation in Lisp or Dylan than in C++ for at least some uses of each pattern
16 of 23 patterns are either invisible or simpler

那末哪些形式变得“invisible”,哪些是“simpler”了呢?

《Design Patterns》中讲设想形式大抵分为三类

  • Creational: ways and means of object instantiation
  • Structural: mutual composition of classes or objects (the Facade DP is Structural)
  • Behavioral: how classes or objects interactand distribute responsibilities among them

因为在动态范例言语中,类(class, type)和要领(function)都是一等国民,因而Creational patterns在动态范例言语,如Python中就变得“invisible”。

因为动态范例、ducking type,一些Creational patterns如“Observer”,“Visitor”就变得“simpler”。这里要强调的是,变得更简朴,并不意味这个这个形式就没有存在的意义了,比方观察者形式,或许定阅-宣布,代表了松耦合的设想准绳,在各个层级的设想中都是须要的。

关于这类表现更高准绳、头脑的设想形式,我们应当用形式去协助思索和沟通,而不要拘泥于榜样代码、特定言语完成。StackExchange上的这个排比句很适当:

- I might say that I have a visitor pattern, but in any language with first class functions it will be just a function taking a function. Instead of factory class I usually have just a factory function.
- I might say I have an interface, but then it's just a couple of methods marked with comments, because there wouldn't be any other implementation (of course in python an interface is always just comments, because it's duck-typed). 
- I still speak of the code as using the pattern, because it's a useful way to think about it, but don't actually type in all the stuff until I really need it.

那末回到题目,设想形式是言语相干吗(language-specific)?

我的回覆是,部份设想形式是言语相干的,部份设想形式不是言语相干的,详细到某一个特定的形式还多是变化的。

为何呢,严谨一点,我们只能说设想形式是题目相干的 -- 是关乎某个题目的。中心在于,这个题目在什么情况下确实是一个题目。而且,跟着生长,一个老题目会灭亡,新题目会涌现。

详细到编程言语,则应当体贴的是一个题目是不是是言语相干的。在静态范例言语,如C++中,对象都有范例,范例决议了其行动,那末为了运转时多态,就得有一个虚基类,同时还要做到OCP,这就须要形形色色的Creational Patterns。但到了动态范例言语,这个就不再是一个题目,因而就不再有与之对应的形式。

references

  • clean architecture
  • Design Patterns: Elements of Reusable Object-Oriented Software
  • Are there any design patterns that are unnecessary in dynamic languages like Python?
  • Design Patterns in Dynamic Programming
  • 解密“设想形式”
  • Design Patterns in python
  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
SOLID准绳、设想形式适用于Python言语吗

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282236.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>