假设有一个验证密码的需求,会有很多限制条件,比如密码长度大于某一值,密码字符不全为数字,密码字符不全为字母等等。
最简单粗暴的方法如下:
def valid_password(pwd=''):
if len(pwd)<6:
raise ValueError('Passwords must be at least 6 characters')
if pwd.isalnum():
raise ValueError('Passwords must contain at least one special character')
...
当然由于需求很简单,所以堆在一个方法中也不觉得很糟糕,但是如果这样的if变得很多,很复杂,这么堆积就不可取了。
现在就用插件的方式来处理:
定义一个元类,使密码验证的基类在被继承时自动添加子类”插件“
class PluginMount(type):
def __init__(cls,name,bases,attrs):
if not hasattr(cls,'plugins'):
cls.plugins=[]
else:
cls.plugins.append(cls)
创建密码验证基类,也就是总的”插件“管理器:
class PasswordValidator(object):
__metaclass__=PluginMount
def validate(self,pwd):
raise NotImplementedError()
创建各个子类密码验证”插件“:
长度验证:
class MinimumLength(PasswordValidator):
def validate(self,pwd):
if len(pwd)<6:
raise ValueError('Passwords must be at least 6 characters')
字符验证
class SpecialCharacters(PasswordValidator):
def validate(self,pwd):
if pwd.isalnum():
raise ValueError('Passwords must contain at least one special character')
等等验证。。。
最终密码验证方法:
def valid_password(pwd=''):
for plugin in PasswordValidator.plugins:
plugin().validate(pwd)
看起来确实多了很多代码,但是好处也是很明显的。在之前的密码验证方法中,如有任何修改,都需要修改原方法,而且密码验证会随着需求的增多而变得越来越难维护;
在新的插件方式中,如果你有新的需求,直接添加密码验证子类即可完全不影响密码验证的方法,各个验证方法还可以分开管理,结构也非常清楚。