iT邦幫忙

2022 iThome 鐵人賽

DAY 4
0

一個Module的內部應該包含哪些功能?
這時候就要回到module的責任來看了
責任分析一般會包含兩個角度

  1. 高階/低階
  2. 內聚/耦合
    簡單來說越高階,越接近API的程式碼就要越接近商業邏輯
    越低階的程式碼就要越接近底層實現

舉個例子,假設一段商業邏輯的目的是為了把檔案從s3的A bucket下載到檔案系統內,並且重新命名

class BussinessLogicExecutor():
    def download_from_bucket(self, key, download_path):
        boto3.client('s3').download_file(SOURCE_BUCKET, key, download_path)
    
    def rename_files(self, file_paths):
        for i, file in enumerate(file_paths):
            self.download_from_bucket(file, file)
            path = Path(file)
            path.rename(i)

乍看之下沒什麼問題,而且每個函數只做了一件事,完美?

問題在於如果有一天發現單檔下載太慢要改async呢?
其他地方也要有這個功能呢?
所以勢必要把這兩者拆開,那如果是以下這個狀況呢?

class BussinessLogicExecutor1():
    def download_from_bucket(self, key, download_path):
        boto3.client('s3').download_file(SOURCE_BUCKET, key, download_path)
    
    def rename_files(self):
        
        for i, file in enumerate(file_paths):
            self.download_from_bucket(file, file)
            path = Path(file)
            path.rename(i)
    
    def get_filelist_from_google_sheet(self):
        result = sheetService.spreadsheets().values().get(
            spreadsheetId=spreadsheet_id, range=range_name).execute()

這個跟上面一樣,當然要拆開
問題來了,幾個呢?
就跟這時候就可以回到上一章的SOLID原則對吧
根據SRP
這就應該拆成

  1. 商業邏輯
  2. Google Sheet API
  3. Accesss S3
    三個責任分開處理
    所以我們可以這樣歸納,一般來說在實現商業邏輯的那一層,如果大量使用了第三方的API/實作的底層
    那就應該考慮是不是要拆分了

那平行的商業邏輯呢?

class API_A(Resource):
    @staticmethod
    def sanitize(request):
        page = request.args['page']
        page_size = request.args.get('page_size', 10)
        assert page
        assert page_size
        return page, page_size

    def get(self, request):
        page, page_size = self.sanitize(request)
 
class API_B(Resource):
    def get(self, request):
        page, page_size = API_A.sanitize(request)

這很明顯就是降低內聚性了
所以收到這種MR有兩個角度可以退回去

  1. 耦合過高
  2. 違反SRP
    這時候最好的改法就是將sanitize這種責任再單獨丟出去
    可以最大限度減少函數的重工
    所以其實在明確責任範圍的情況下,只要能夠產生低耦合高內聚
    就可以讓開發者更容易找到他要的功能在什麼位置
    具體還可以參考以下幾個指標
  3. 檔案開頭import了多少東西(Python內部6~8個已經很多了,超過12個就很難容忍了)
  4. 有沒有出現A module從頭到尾都在call B module的狀況
    如果符合以上兩點,就應該考慮敲comment / issue進行重構

上一篇
D3 - SOLID就夠了嗎?淺談SOLID原則的誤解與誤用
下一篇
D5 - 我把參數都組合好放在那裡了 - DTO的運用
系列文
寫個好的lib大家用吧!那些好用的lib常見的套路與想法25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言