2014-09-25 132 views
-1

它是不好的做法,如果是這樣,爲什麼要返回子類的實例作爲父類實例的方法的輸出?返回子類實例的父方法

例如,可以將以下 -

class Parent(object): 
    def __init__(self, attr): 
     self.attr = attr 

    def child(self, typ): 
     if typ == 'a': 
      return ChildA(self.attr) 
     else: 
      return ChildB(self.attr) 

class ChildA(Parent): 
    pass 

class ChildB(Parent): 
    pass 

是一個好的設計?

+0

這不是意見的問題嗎?我們不知道有堆棧溢出的意見。 – Veedrac 2014-09-25 09:04:17

+0

我在考慮有關軟件設計的「什麼是良好實踐」的問題是可以接受的。在SO中尋找「良好實踐」,你會發現很多高投票的問題,即使並不總是清楚有一個明確的答案。 – Bach 2014-09-25 09:09:45

+0

其中大部分來自「舊」堆棧溢出,並且大部分(應該)已經關閉。 – Veedrac 2014-09-25 09:12:41

回答

1

我期待有人能夠更有知識地回答這個問題,但由於這還沒有發生,我會投入我的兩分錢的價值。我會嘗試解決這種設計的技術問題,併爲專業人士進行更高層次的分析。

我認爲這確實不是很好的做法。由於多種原因,父類不應該意識到子類,但首先它會使未來擴展模塊變得更加困難。每當新的子類對子類(或其子類)進行子類化時,它可能也需要更新父類。在Python中,爲了避免循環導入,它強制將所有將來的子類別定義在同一個文件中。雖然這兩個問題都可能被繞開,但這似乎是不必要的麻煩。另外,由於指定的方法是在子類中繼承的,因此除非被覆蓋,否則會觸發「兄弟」類之間的某種熟悉,這可能不是所期望的。

儘管我確定在某些情況下,父類應該知道它的子類是有用的,但我認爲一般情況下,這種情況會推斷設計中的錯誤和另一種解決方案,涉及這種內省應該追求。

請注意,這並不意味着父對象不應該知道子對象。像任何其他對象一樣,子對象可以作爲參數在父方法中進行合法接收。父對象甚至可以將它們當作父對象,因爲子對象也是父對象,這是OOP的一個要點。

關於你的具體例子,這可以通過factory design pattern來實現。創建的對象不需要與其創建者的實例相同。例如:

class factory(object): 
    def __init__(self, attr): 
     self.attr = attr 

    def create(self, typ) 
     if typ == 'a': 
      return ChildA(self.attr) 
     else: 
      return ChildB(self.attr) 

class Parent(object): 
    def __init__(self, attr): 
     self.attr = attr 

class ChildA(Parent): 
    pass 

class ChildB(Parent): 
    pass 
相關問題