2017-06-26 51 views
1

我有兩個類需要在彼此之間傳遞數據。第一類實例化第二個類。第二類需要能夠將信息傳遞迴第一類。但是我無法再從第二類實例化ClassOne。兩個類都運行共享計時器,在這些計時器中輪詢不同的事情,因此當他們共享計時器時,他們無法共享他們輪詢的對象。通過Classess傳遞數據與實例化類

我目前的解決方案(工作)是傳遞一個方法到ClassTwo並用於發送數據備份,但我覺得這可能有點黑客和錯誤的方式去解決它。

classOne(): 

    def __init__(self,timer): 
     self.classTwo = classTwo(self.process_alerts,timer) 
     self.classTwo.start 

    def process_alerts(alert_msg): 
     print alert_msg 


classTwo(): 

    def __init__(proses_alerts,timer) 
     self.process_alerts = process_alerts # <----- class ones method 

    def start(self): 
     check for alerts: 
      if alert found: 
       self.alert(alert_msg) 


    def alert(self,alert_msg): 
     self.process_alert(alert_msg) # <----- ClassOnes method 

謝謝你的時間。

+0

提示未來:在評論中放置標記,以便代碼仍然有效:)。 –

+0

您可以將'@ staticmethod'註釋添加到'process_alerts'。 –

+0

你爲什麼不繼承第一課的第二課? 'class Two(One):...' –

回答

2

沒有什麼能阻止你傳遞當前ClassOne實例(self),以它自己的ClassTwo例如:

class ClassOne(object): 
    def __init__(self): 
     self.two = ClassTwo(self) 
     self.two.start() 

    def process_alert(self, msg): 
     print msg 

class ClassTwo(object): 
    def __init__(self, parent): 
     self.parent = parent 

    def start(self): 
     while True: 
      if self.has_message(): 
       self.parent.process_alert(self.get_message()) 

注意,在這種情況下「家長」意味着它是一個包含關係(「有」),它與繼承無關(「是」)。

如果你是什麼臭蟲ClassOne負責instanciating ClassTwo(這的確引入強耦合),您可以更改ClassOne所以它需要一個工廠:

class ClassOne(object): 
    def __init__(self, factory): 
     self.other = factory(self) 
     self.other.start() 

#等

和然後通過ClassTwo作爲工廠:

c1 = ClassOne(ClassTwo) 

所以你可以實際上通過任何與右側接口返回一個對象(使得單元測試更容易)

或者 - 至少在你的(我假設條紋向下)的例子 - 你可以只讓ClassOne通本身ClassTwo.start(),並明確地傳遞ClassTwo實例ClassOne ,即:

class ClassOne(object): 
    def __init__(self, other): 
     self.other.start(self) 

    def process_alert(self, msg): 
     print msg 


class ClassTwo(object): 
    def start(self, parent): 
     while True: 
      if self.has_message(): 
       parent.process_alert(self.get_message()) 


c2 = ClassTwo() 
c1 = ClassOne(c2) 

或者也可以簡單從ClassOne刪除調用ClassTwo.start,你不需要ClassOne.__init__ClassTwo實例的任何引用:

class ClassOne(object): 

    def process_alert(self, msg): 
     print msg 


class ClassTwo(object): 
    def start(self, parent): 
     while True: 
      if self.has_message(): 
       parent.process_alert(self.get_message()) 


c1 = ClassOne() 
c2 = ClassTwo() 
c2.start(c1) 

這是因爲脫鉤,因爲它可以,但如果ClassTwo只需要在start()ClassOne實例,並從startClassOne調用的方法並不需要保持對ClassTwo實例的引用,要麼只適用。

2

您可以刪除/最小化類之間的耦合!我發現這種architecture地圖非常適合通過Queue進行通信來共享數據。

通過使用隊列,您可以分離兩個類。生產者(ClassTwo)可以檢查消息,並將它們發佈到隊列中。它不再需要知道如何正確實例化一個類或與它進行交互,它只是傳遞一條消息。

然後,一個ClassOne實例可以從隊列中提取消息,因爲它們變得可用。這也可以很好地擴展彼此獨立的每個實例。

ClassTwo -> publish to queue -> Class One pulls from queue. 

這也有助於測試,因爲兩個類是完全隔離的,您可以爲任一類提供一個隊列。


隊列通常也提供支持阻塞,直到消息變爲可用,所以你不必來管理超時操作。

+0

非常感謝您的回答。在我的情況下,布魯諾的答案沒有執行任何額外的事情,所以我標記了他的正確答案。 – AdamR