Join Jungwoo Ryoo for an in-depth discussion in this video Observer example, part of Python: Design Patterns.
- So we start with the Subject class which represents what is being observed. So the Subject class keeps this list called _observes which is where references to all the observers are being kept. So note that this is a one to many relationship. There'll be only one subject who will be observed by multiple observers. Next is defining the attach method and this method accepts an observer as an argument.
So with this observer object, we'll be, first of all, checking if the observer is not already in the observers list. So, add if observer not in self_observers So only when this observer is not already in the observers list then we'll try to append the observer to the list. So that's the next statement.
So self_observers.append The next method is the detach method and this is simply removing the observer from the observers list. And then the last method is our notify method. This is probably the most important method in the subject class because this is what notifies all the observers when there is a change in the subject.
So what we want to say is for all the observers in the list type for observers in the the observers list self._observers You want to say don't notify the observer who's actually updating the temperature because this is what we're basically doing later on with the core class. So here, we're simply making sure that the observer is not notified if the observer is the one that's actually changing the value if the observer is actually updating the value.
So simply type if modifier is not the same as the observer then we can alert the observers. So the statement says observer.update and we will be iterating through all the observers in the observers list. So we'll be notifying all the observers by invoking their update method.
Now the next class is our Core class which is inheriting from the Subject class and you can see that by this keyword Subject. So by putting this Subject keyword in between the parentheses, we're indicating that we're inheriting from the Subject class. In the init method of the Core class we're setting the name attribute based on the argument in the init method and then the temperature is simply set to zero initially.
So one of the most important attributes of this Core class is the temperature. And if the temperature changes, the observers of this Core class will be notified. And then we define the Getter that gets the core temperature and then we have a Setter that sets the core temperature like this. And then we have our TempViewer class which is an observer class we're defining. So the only method we're defining in the observer class is this method called update which gets invoked whenever, in this case, the temperature value, gets changed.
So like I said, this is an alert method that is invoked whenever the notify method in a concrete subject is invoked. So all it does is simply display this message saying that temperature viewer so and so, in this case, a particular object, has temperature value such and such based on the actual core temperature. So we're done with defining our classes. Now let's actually try to use these classes by first creating our subject.
So there are going to be two subjects: core 1 and core 2 but we'll be using the same class Core. We'll name the cores differently, Core 1 Core and then Core 2. And then it's time for us to create our observers. The class representing our observers is called TempViewer. So type TempViewer and then we need another instance of TempViewer.
TempViewer. Now let's attach these observers to our first core. So c1.attach and v1 is the first observer. And then we'll be attaching the second observer, which is v2. attach(v2). So now we are ready to test our code. One of the ways of testing our code is by changing the temperatures because that's when the observers get notified.
So we set the temperature to 80 first and then we set the temperature to 90 and let's see what happens. So in this case, whoever is changing the temperatures have nothing to do with the observers so both of the observers will get notified both times. So we'll have four outputs. So go to Tools, click on Build, let's see what happens. So we seem to have an error here, let's see what the problem is, go to line 18. So I see an error here which is this extra s because this has to be an individual observer instead of the observers list.
Let's try it again. Go to Tools, click on Build. Okay I missed another one here which is self and let's try to run it again. Build. I forgot the colon here too so let me do this and then try. Click on Tools and Build and then another colon here. Let me try again. Tools, Build. And then finally here I have also a little bit of problem.
Line 8. self_, another typo. So now it should work. Tools, Build. And then the append takes an argument which is observer. So now it should be all fixed. Go to Tools, click on Build. Yes, and it worked.
- Understanding design patterns
- Best design practices: consistency, completeness, and correctness
- Working with creational patterns
- Working with structural patterns
- Working with behavioral patterns
Skill Level Intermediate
Q: In the strategy pattern example, why does the code keep executing the default function rather than the alternate?
A: The programming demonstration skips the step of defining what the strategy pattern should be when an alternate function name is provided
as an argument as shown below.