在面向對象系統的分析與設計過程中經常會遇到這樣一種情況: 一個流程可以分爲A,B,C….多個步驟,但在具體的步驟中可能會有不同的情況出現,這時就Template模式就非常有用:
class P(object):
def a():
pass
def b():
pass
def operate():
a()
b()
class Sub(P):
def a():
print 'a in sub'
def b():
print 'b in sub'
class Suba(P):
def a():
print 'a in suba'
def b():
print 'b in suba'
也就是說在父類中定義流程的細節,步驟的接口,在子類中無需管流程的細節,只要實現步驟的細節即可以滿足功能的需求了。
最近做的一個Flask項目就用到了Template模式,在route中接受到的post請求需要驗證,而wtf已經提供了一些基本格式的驗證,這時想把一些功能上的驗證也做到裏面去,不討論這麼做是不是符合面向對象的一些原則,在這個項目中很方便也不會有問題就好!於是新建了一個類:
class AgentForm(Form):
status = 0
msg = ''
domain = ''
user_id = ''
def set_domain(self, domain):
self.domain = domain
def set_user_id(self, user_id):
self.user_id = user_id
def validate_logic(self):
return True
def validate(self):
if self.validate_logic(): # subclass validation is OK, run the basic validation for format
if not super(AgentForm, self).validate():
self.status = FORMAT_VALIDATION_FAILED_RET
errors = deepcopy(self.errors)
if 'csrf_token' in errors:
del errors['csrf_token']
for value in errors.itervalues():
self.msg += string.join(value, sep=' ')
self.msg += '\n'
self.msg = self.msg[0:len(self.msg)-1]
# self.msg = str(self.errors)
return False
return True
return False
這個類的目的在於將wtf本身的驗證信息返回到成員變量status,msg裏面來,方便調用者獲取。同時提供validate_logic函數接口,子類只需要重載validate_logic函數,並在出現錯誤時爲status,msg賦值即可。子類示例:
class ForgetPwdForm(AgentForm):
email = StringField('email', validators=[
DataRequired(message=u'請填寫者電子郵件'),
Email(message=u'Email格式不正確')
])
def validate_logic(self):
user = User.query.filter_by(email=self.email.data, domain=self.domain).first()
if not user:
self.status = 1
self.msg = u'此賬號不存在'
return False
return True