2009-09-09 60 views
1

3類,A包含B,B包含C.所以用戶要使用一些C的服務,有兩種選擇:更少的API或更多的封裝?

首先,更多的封裝:中

class A: 
    def newMethod(self): 
     self.b.newMethod() 

class B: 
    def newMethod(self): 
     self.c.newMethod() 

class C: 
    def newMethod(self): 
     #do something 
     pass 

a.newMethod() 

呼叫服務C直接:

class A: 
    pass 

class B: 
    pass 

class C: 
    def newMethod(self): 
     #do something 
     pass 


b = a.b 
c = a.c 
c.newMethod() 

一般來說,我從書本上學到的東西告訴我,第一選擇更好。
但是當C有許多方法暴露給外部用戶時,第二個選擇似乎更合理。在第一個設計中,A和B沒有真正有用。

您會選擇什麼?

回答

3

讓你的對象爲你做事,而不是要求他們提供他們的數據和做它的東西。

如果c在您的例子暴露了很多方法,我建議你不應該你的客戶公開這些以a和,而是ab應共同努力,用代表的這些方法客戶。

問題的一個很好的指標是一個包含數據併爲這些數據項提供getter的類,以及訪問該數據然後執行工作(DAO除外)的客戶端代碼。在這種(常見的)場景中,類很可能不應該暴露該數據(也可能是破壞封裝),而是爲該客戶端(通過具有該功能,或者可能是一些可注入的策略對象)執行該項工作。

查看Law of Demeter(鏈接的文檔看起來相當乾燥和學術,令人遺憾),它提供了關於對象和成員應該如何通信的一些很好的指導。

+0

當然,一般來說,書會說。 但讓我解釋更多。這不僅是因爲C公開了很多方法,這是因爲還有C1,C2,C3,它們負責爲外部用戶代碼提供服務。 當然,我可以隱藏所有的B,C,C1並向A中添加很多方法,所以用戶代碼看不到我的庫的內部部分 但是,這實際上並沒有意義。 A只是直接向B和其他負責的類傳遞參數。 根據SRP,A應該只有一個責任,A不應該做B或C的工作,它只是讓用戶找到一個地方B – lilyonwind 2009-09-09 13:04:52

+0

隱藏B/C/C1/C2的另一個問題是用戶代碼無法訪問事件的他們。這意味着A從圖書館內部向外部傳送每一個事件,我認爲很多無用的工作。 – lilyonwind 2009-09-09 13:11:11