2017-06-20 47 views
1

我有一個RoundRobinCheckerPlayoffChecker類,它們都從ViolationChecker繼承,它檢查給定的循環法或淘汰賽匹配是否通過規則。根據自變量來檢驗不同的子類

構造函數有一個參數,匹配項:ViolationChecker(match)。現在,如果比賽是季後賽(match.playoff),則應該實例化PlayoffChecker,否則應該是RoundRobinChecker。我可以這樣做:

checkers = [PlayoffChecker(match) if match.playoff else RoundRobinChecker(match) for match in matches] 

但是,這是一種不乾淨的做法。是否可以調用父類的構造函數ViolationChecker(match),這會創建相應子類的實例?

我可以在這裏用什麼設計以透明的方式選擇適當的類?

回答

2

爲了使ViolationChecker(match)的工作,我們可以覆蓋在你的父類的__new__ method這樣的:

class ViolationChecker: 
    def __new__(cls, match): 
     if match.playoff: 
      cls= PlayoffChecker 
     else: 
      cls= RoundRobinChecker 

     inst= object.__new__(cls) 
     return inst #implicit call to inst.__init__(match) 

然而,這不是很明顯的人誰讀取您的代碼ViolationChecker(match)返回一個子類的實例。我建議增加一個明確名稱的靜態方法來ViolationChecker,這樣的事情:

class ViolationChecker: 
    @staticmethod 
    def new_for_match(match): 
     if match.playoff: 
      cls= PlayoffChecker 
     else: 
      cls= RoundRobinChecker 

     inst= cls(match) 
     return inst 

現在你可以做ViolationChecker.new_for_match(match),這體現了該match實例創建一個專門ViolationChecker更明確的意向。