為什么要模塊化編程開發(fā)?
Python,最偉大的地方就在于Python擁有各種強大的庫。所以,使用Python進行開發(fā)工作,最重要的也是要學(xué)會使用Python庫,不去重復(fù)造輪子,那么在Python-Web開發(fā)中,也要學(xué)會將功能模塊化,這樣做不僅可以降耦,還會在團隊開發(fā)或者多項目開發(fā)中,做到敏捷開發(fā),而且在項目升級中,更容易做到維護/重構(gòu)。所以,在開發(fā)中,做到模塊化開發(fā),是很有必要的。
那么,根據(jù)我自己的經(jīng)驗談一談,我在Flask開發(fā)Web應(yīng)用/Api服務(wù)的時候怎么做到模塊化開發(fā)。
下面是一個Flask應(yīng)用的層級關(guān)系,后面的講解,將會根據(jù)這個層級來說明怎么進行模塊化編程開發(fā)。
.
├── ERROR_CODE.MD
├── README.md
├── app App應(yīng)用
│ ├── __init__.py
│ ├── api API模塊
│ ├── config 配置模塊
│ ├── handler 邏輯處理模塊
│ ├── libs 內(nèi)部庫
│ ├── models
│ ├── static
│ ├── templates
│ ├── utils 工具類模塊
│ └── view 視圖模塊
├── env Python庫
├── logs
├── requirements.txt
└── run.py 運行腳本
這是一個簡單的完整的Flask項目層級關(guān)系,模塊化的主要核心在于api、handler、view這三個部分。
通常的,我們把對外提供API服務(wù)的處理放在api模塊里面,把業(yè)務(wù)邏輯處理部分放在handler里面,把提供頁面展示與頁面處理的邏輯放在view里面。
1. API模塊: api
主要處理對外提供API接口的代碼。
在這里面,我們盡量不做對數(shù)據(jù)邏輯的處理,只處理業(yè)務(wù)邏輯,比如我們有一個創(chuàng)建員工郵箱的接口:
@user_mail_bp.route('/user', methods=['POST'])
def user_mail_create():
"""創(chuàng)建郵箱"""
mail = get_json('mail', u'郵箱', valid=[Required()])
name = get_json('name', u'名稱', valid=[Required()])
info = {}.update(mail=mail, name=name)
# 1. 請求企業(yè)郵箱接口創(chuàng)建郵箱
res, data = user_exmail.create_with_user_info(user=info)
if res is not True:
msg = data
return error(msg=msg)
# 2. 將創(chuàng)建的郵箱存放到數(shù)據(jù)庫
res, data = user_handler.create_with_user_info(user=info)
if res is not True:
msg = data
return error(msg=msg)
return success(msg=u'請求成功', data=data)
這個接口示例中,我們主要有兩個部分的處理,第一個是解析參數(shù)與返回結(jié)果,第二個是生成郵箱并保存到數(shù)據(jù)庫??梢钥吹?,我們并沒有把步驟1中怎么調(diào)用企業(yè)郵箱接口創(chuàng)建郵箱的邏輯和步驟2中怎么保存到數(shù)據(jù)庫的邏輯放在這里,而是調(diào)用函數(shù)去處理的,我們只去分析操作結(jié)果。
那么,這樣做的好處是什么呢?
低耦合性。是的,我們不去關(guān)心該怎么去創(chuàng)建郵箱,只關(guān)心業(yè)務(wù)的部分:為誰創(chuàng)建郵箱,創(chuàng)建結(jié)果如何。這樣,即使創(chuàng)建郵箱的方式變化了,只需要在創(chuàng)建郵箱的函數(shù)里去處理,或者直接更改調(diào)用的函數(shù)就可以了,極大的減少了工作量。
在上面的代碼中,我們使用user_exmail.create_with_user_info(user=info)去創(chuàng)建郵箱,那么,這個函數(shù)又是什么呢?這就需要說說handler模塊了。
2. handler模塊
數(shù)據(jù)請求、數(shù)據(jù)操作等邏輯處理代碼主要封裝在這里。
比如上面談到的user_exmail.create_with_user_info(user=info)函數(shù):
def create_with_user_info(user_info):
"""
新建用戶企業(yè)郵箱
:param user_info: dict,包含為用戶信息
:return: 創(chuàng)建結(jié)果 True,group / False,msg
"""
mail = user_info.get('mail', None)
name = user_info.get('name', None)
if not mail:
msg = u'mail不允許為空'
return False, msg
if not name:
msg = u'name不允許為空'
return False, msg
# 請求接口創(chuàng)建群組
try:
res = exmail_store.create_user(
mail=mail,
name=name
)
except Exception as e:
msg = u'企業(yè)郵箱接口異常:{}, 請聯(lián)系管理員'.format(e.message)
return False, msg
# 解析創(chuàng)建群組返回值
if not res:
msg = u'企業(yè)郵箱接口異常, 返回值為空, 請聯(lián)系管理員'
return False, msg
res_data = json.loads(res.text)
err_code = res_data.get('errcode', None)
if err_code != 0:
msg = res_data.get('errmsg', None)
return False, msg
return True, group
這里把創(chuàng)建企業(yè)郵箱的請求單獨封裝起來,放在handler中,這個邏輯一旦完成,即函數(shù)編寫完成,只需要在外部調(diào)用就夠了。如果函數(shù)不滿足使用,比如創(chuàng)建郵箱方式變化了,或者API升級了,那么我們只需要重新編寫一個函數(shù)就可以,這樣既保留原有函數(shù)功能,也保證升級后的函數(shù)功能,對調(diào)用方來說可以做到兼容。
同樣的,如果有新的項目,有相同的功能需求,我們只需要把該函數(shù)移植過去就可以了,這是模塊化的編程的另一種好處:可移植性。
3. view視圖模塊
該部分和API模塊部分類似,只是處理的是返回頁面的路由,這里不多做解釋,給大家一個test模塊的示例:
@test_view.route('/t/test')
def home():
mail = get_json('mail', u'郵箱', default='')
if not mail:
return render_template('test/error.html')
# 創(chuàng)建郵箱部分
······
return render_template('test/success.html')
Python模塊化編程開發(fā)還有一個重要的好處:團隊合作,敏捷開發(fā)。由于是模塊化,多人開發(fā)的時候,只需要分工不同的模塊,每個人負責的模塊只需要提供函數(shù),別人調(diào)用就行,先提供函數(shù)模擬返回參數(shù),后進行邏輯開發(fā),這樣在互不干涉的工作中,快速完成自己負責的部分,進而完成整個項目開發(fā)任務(wù)。