# SOLID原则、设计模式适用于Python语言吗

SOLID是面向对象设计的指导原则，更具适用性的应该是各种设计模式，GOF经典的Design Patterns: Elements of Reusable Object-Oriented Software 也是用C++来举例的，那么这些经典设计模式有多少是适用于动态语言如python的呢？本文记录对这些问题浅薄的思考，如果有认知错误的地方，还请大家不吝指教。

# 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

This fact could lead you to conclude that the ISP is a language issue, rather than an architecture issue.

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 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中的依赖与依赖倒置

'''my.py'''
import other
class My(object):
def f(self):
other.act()


'''my.py'''
class My(object):
def __init__(self, actor):
self._actor = actor

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


'''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的。

# 设计模式

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

# 设计模式与动态语言

《Design Patterns》这本书，写于1994年，作者提到写这本数的目标，就是将这些行之有效的经验记录下来。前面提到，设计模式是针对一类问题的解决方案，那么在介绍一种设计模式的时候，就一定会涉及到以下内容（包括但不限于）：

• 要解决的问题是什么
• 解决方案是什么样子的
• 解决方案的缺陷与适用场景
• 解决方案的详细步骤
• 针对同一个问题，有没有其他解决方案，各自的优劣

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

《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

- 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.


# references

posted @ 2019-11-04 09:37  xybaby  阅读(1602)  评论(3编辑  收藏  举报