Ada
Ada

Reputation: 97

Passing data accross Classess with out instantiating the class

I have two classes that need to pass data between each other. The first class instantiates the second. The second class needs to be able to pass information back to the first. However I cannot instantiates the ClassOne again from class two. Both classes are running off a shared timer where they poll different things so while they share the timer they cannot share the objects they poll.

My current solution (that works) is to pass a method to ClassTwo and used to send data back up but I feel this might be a bit hack-ey and the wrong way to go about it.

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

Thank you for your time.

Upvotes: 1

Views: 73

Answers (2)

dm03514
dm03514

Reputation: 55932

You could remove/minimize the coupling between the classes! I found this sort of architecture maps really well to sharing data by communicating across a Queue.

By using Queue you can decouple the two classes. The producer (ClassTwo) can check for messages, and publish them to a queue. It no longer needs to know how to correctly instantiate a class or interact with it, it just passes a message.

Then a ClassOne instance could pull messages from the queue, as they become available. This also lends well to scaling each instance independent of each other.

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

This also helps with testing as the two classes are completely isolated, you can provide a Queue to either class.


Queues also usually provide operations that support blocking until message becomes available, so you don't have to manage timeouts.

Upvotes: 2

bruno desthuilliers
bruno desthuilliers

Reputation: 77902

Nothing prevents you from passing the current ClassOne instance (self) to it's own ClassTwo instance:

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())

Note that in this context "parent" means it's a containment relationship ("has a"), it has nothing to do with inheritance ("is a").

If what bugs you is that ClassOne is responsible for instanciating ClassTwo (which indeed introduce a strong coupling), you can either change ClassOne so it takes a factory:

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

# etc

and then pass ClassTwo as the factory:

c1 = ClassOne(ClassTwo)  

So you can actually pass anything that returns an object with the right interface (makes unittesting easier)

Or - at least in your (I assume striped down) example - you could just make ClassOne pass itself to ClassTwo.start() and explicitely pass ClassTwo instance to ClassOne, ie:

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)

Or even simpler remove the call to ClassTwo.start from ClassOne and you don't need any reference to a ClassTwo instance in ClassOne.__init__:

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)

which is as decoupled as it can be but only works if ClassTwo only needs ClassOne instance in start() and methods called from start and ClassOne doesn't need to keep a reference on the ClassTwo instance either.

Upvotes: 2

Related Questions