for sleek and fashionable code
两天重要原则
Duck Typing
如果该对象的行为像鸭子, 就可以认为是鸭子
鸭子类型出现在动态语言中(dynamic languages
)不具备强类型, 不需要指定类型就可以调用对象的一个存在的方法.
如下: 为业务向的代码, 有两种实现方法:
DBclass
然后重写父类的方法object composition
的形式去组织inheritance.py
class User(Dbclass):
pass
object composition
class User(object):
_persist_methods = ['get', 'save', 'delete']
def __init__(self, persister):
self._persister = persister
def __getattr__(self, attribute):
if attribute in self._persist_methods:
return getattr(self._persister, attribute)
Behavioral Patterns
为对象之间的交互而生. 根据GOF principles, 有11种
Chain of responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template, Visitor.
Iterators
是Python的内建模式, 可以通过了解Python iterators, generators
来学习Iterators
Chain of responsibility
举例: 设计一个网页屏蔽器, 具体屏蔽内容有: 广告, 色情内容, 等等, 可以设计如下: 通过ContentFilter
来统一管理和组织不同的过滤器.
class ContentFilter(object):
def __init__(self, filters=None):
self._filters = list()
if filters is not None:
self._filters += filters
def filter(self, content):
for filter in self._filters:
content = filter(content)
return content
filter = ContentFilter([
offensive_filter,
ads_filter,
porno_video_filter])
filtered_content = filter.filter(content)
Command
: 举例: 设计python命令行, 可以如下设计: 定义基本命令类, 然后使用History
封装队列来统一处理
class RenameFileCommand(object):
def __init__(self, from_name, to_name):
self._from = from_name
self._to = to_name
def execute(self):
os.rename(self._from, self._to)
def undo(self):
os.rename(self._to, self._from)
class History(object):
def __init__(self):
self._commands = list()
def execute(self, command):
self._commands.append(command)
command.execute()
def undo(self):
self._commands.pop().undo()
history = History()
history.execute(RenameFileCommand('docs/cv.doc', 'docs/cv-en.doc'))
history.execute(RenameFileCommand('docs/cv1.doc', 'docs/cv-bg.doc'))
history.undo()
history.undo()
Singleton
: 保证了给定的类在运行期只有一个实例. 在Python中我们可以修改实例化的进程通过修改 __new__()
, 如cls._logger存在则返回, 不存在则调用__new__
其中 cls._logger
:为类变量
class Logger(object):
def __new__(cls, *args, **kwargs):
if not hasattr(cls, '_logger'):
cls._logger = super(Logger, cls).__new__(cls, *args, **kwargs)
return cls._logger
python 单例模式使用有如下三种:
top-level
创建app, 或者在config.py
文件中dependency injection
依赖注入是一种有效的简单控制的机制用来暴露一部分API接口, 封装的API接口给客户
Python design pattern