Computer Science

Observer Pattern

The Observer Pattern is a design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. This pattern is used to achieve loose coupling between objects and to allow for one-to-many communication between them.

Written by Perlego with AI-assistance

7 Key excerpts on "Observer Pattern"

  • Book cover image for: Learning Python Design Patterns - Second Edition
    Behavioral patterns, as the name suggests, focus on the responsibilities that an object has. They deal with the interaction among objects to achieve larger functionality. Behavioral patterns suggest that while the objects should be able to interact with each other, they should still be loosely coupled. We will learn about the principle of loose coupling later in this chapter.
    The Observer design pattern is one of the simplest Behavioral patterns. So, let's gear up and understand more about them.
    Passage contains an image

    Understanding the Observer design pattern

    In the Observer design pattern, an object (Subject) maintains a list of dependents (Observers) so that the Subject can notify all the Observers about the changes that it undergoes using any of the methods defined by the Observer.
    In the world of distributed applications, multiple services interact with each other to perform a larger operation that a user wants to achieve. Services can perform multiple operations, but the operation they perform is directly or heavily dependent on the state of the objects of the service that it interacts with.
    Consider a use case for user registration where the user service is responsible for user operations on the website. Let's say that we have another service called e-mail service that observes the state of the user and sends e-mails to the user. For example, if the user has just signed up, the user service will call a method of the e-mail service that will send an e-mail to the user for account verification. If the account is verified but has fewer credits, the e-mail service will monitor the user service and send an e-mail alert for low credits to the user.
    Thus, if there's a core service in the application on which many other services are dependent, the core service becomes the Subject that has to be observed/monitored by the Observer for changes. The Observer should, in turn, make changes to the state of its own objects or take certain actions based on the changes that happen in the Subject. The above scenario, where the dependent service monitor's state changes in the core service, presents a classical case for the Observer design pattern.
  • Book cover image for: TypeScript 4 Design Patterns and Best Practices
    Chatroom application : You are designing a chatroom application and you create entities for the chatroom, chat users, and inbox. You want to implement a feature to allow two users to communicate with each other via direct messages. You don't want to allow one user to directly receive a reference of another user to send a message. Preferably, you'd use a mediator to trigger message events so that whenever a message is posted, it will forward it to the right recipient.
  • UI elements interacting with each other : You have some UI elements such as an icon with a counter, and in some parts of the application you have a button that, when you click on it, should update that counter after it has performed an operation. You may use this pattern to trigger an event when the button completes the operation so that the mediator will forward a new counter update for that icon.
  • As always, you should always think twice before applying this pattern as you will have to make sure it does not become too big or full of surprises when used in production. Hopefully, if you can apply reason, you will gain lots of benefits from this pattern.
    Next, we will understand more about the Observer Pattern.

    The Observer Pattern

    Observer is a behavioral design pattern that establishes a subscription model of communication. In simple words, you use a publisher object that posts messages to a list of active subscribers either in regard to some events that occur or when a specific rule is activated. Those rules could be some points of interest. For example, say you want to send notifications after a user has registered or some part of your application needs to get an update from a different part of the application.
    This way, you establish a one-to-many communication model between the publisher and the subscriber list. The publisher would not know what the subscriber list looks like. It only allows a reference to an interface that can push messages into it.
    On the other side, the subscriber will receive events from the publisher that it subscribes to and has the choice of acting on or disregarding them. If the publisher somehow gets destroyed, subsequently it will remove any references to the subscriber list so the subscriber will also be lost if it's not used somewhere.
  • Book cover image for: Deciphering Object-Oriented Programming with C++
    View ). The Subject and its View communicate with a one-to-one association. Sometimes Subjects can have multiple Views, in which case the Subject is associated with many View objects. If one View changes, a state update can be sent to the Subject, who can then send necessary messages to the other Views so that they, too, can be updated to reflect how the new state may have modified their particular View.
    The original Model-View-Controller (MVC ) pattern, emanating from early OOP languages such as Smalltalk, has a similar premise, except that a Controller object delegates events between the Model (that is, the Subject) and its View (or Views). These preliminary paradigms influenced early design patterns; the elements of Subject-View or MVC can be seen conceptually as a rudimentary basis for core design patterns today.
    Many of the design patterns we will review in the remainder of this book will be adaptations of patterns originally described by the Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides) in Design Patterns, Elements of Reusable Object-Oriented Software . We will apply and adapt these patterns to solve problems stemming from applications we have introduced in earlier chapters of this book.
    Let’s begin our pursuit of understanding and utilizing popular design patterns by investigating a pattern in action. We will start with a behavioral pattern known as the Observer Pattern .

    Understanding the Observer Pattern

    In the Observer Pattern , an object of interest will maintain a list of observers who are interested in state updates of the main object. The observers will maintain a link to their object of interest. We will refer to the main object of interest as the Subject . The list of interested objects is known collectively as the Observers
  • Book cover image for: Architectural Patterns
    • Pethuru Raj Chelliah, Harihara Subramanian, Anupama Murali, Dr. Kayarvizhy N(Authors)
    • 2017(Publication Date)
    • Packt Publishing
      (Publisher)
    Observer pattern suggests that when one object changes the state, it notifies its dependents and updates automatically. When implementation is in need of one-to-many dependencies, you would want to use this pattern.
    The preceding diagram depicts Observer pattern structure and a sample implementation of the same for a publications app; whenever an event occurs, subscribers need to be informed. The subscribers have a different mode of publishing (SMS, print, and emailing) and may need to support new modes as well in the future, so the best fit is Observer , as we just saw.
    Let's go through its benefits:
    • Enables easy broadcast of communication
    • Supports loose coupling between objects as it's capable of sending data to other objects without any change in the subject
    • Abstract coupling between subject and observer (changes in the observer do not impact subject)
    • Can add or remove Observers any time
    Impacts are as follows:
    • Accidental or unintended updates impact the system heavily as it cascades to the observer down the layers
    • May lead to performance issues
    • Independent notifications may result in inconsistent state or behavior (no handshakes)
    Passage contains an image

    State (objects for states)

    These allow an object to alter its behavior when its internal state changes, and it appears as the class changes. Use state pattern when an object's behavior depends on its state and change at runtime depends on that state.
    The diagram depicts both structure of State pattern and a sample implementation; Context class carries states, and Off and On classes implement State interface so that context can use the action on each concrete class's off/on.
    Listed are the benefits:
    • Suggest localizes state-specific behavior and partitions behavior for different states (new states and transitions can be added easily by subclass definitions)
    • Makes state transitions explicit
    • State objects are shareable
    The impact is, it may make adding a new concrete element difficult.
    Passage contains an image

    Strategy (policy)

    Strategy pattern, also known as policy, defines a family or set of algorithms, encapsulates each one, and make them interchangeable. Strategy lets the algorithm vary independently of the clients that use it. When a group of classes differs only on their behavior, it is better to isolate the algorithms in separate classes and provide the ability to choose different algorithms at runtime.
  • Book cover image for: Pattern-Oriented Software Architecture, On Patterns and Pattern Languages
    • Frank Buschmann, Kevlin Henney, Douglas C. Schmidt(Authors)
    • 2007(Publication Date)
    • Wiley
      (Publisher)
    Here is a brief summary of the pat-tern to clarify what problem and solution are brought together and which roles are introduced: Objects sometimes depend on the state of, or data maintained by, another provider object. If the state of the provider object changes without notice, however, the state of the dependent objects can be-come inconsistent. Therefore, define a change propagation mechanism in which the provider, known as the subject , notifies registered dependents, known as observers , whenever its state changes, so that the noti-fied observers can perform whatever actions they deem necessary. The following diagram captures a sketch of a typical O BSERVER imple-mentation: Structural Variation and Roles The first challenge that arises when trying to develop an all-encompassing generic implementation of a software pattern is that patterns introduce roles for components, as opposed to just introduc-ing components, as discussed in Chapter 1 . Depending on how we ar-range O BSERVER ’ S two main roles—the subject and the observer —we therefore derive distinct, alternative O BSERVER arrangements. For ex-ample, we could assign the role of the subject either to an existing Observer void notify () // Notify all registered observes. for all registered observers do observer.update (); rof end begin register with subject change state start change propagation notify observers pull changed data update service register unregister get_data notify set_data update service 1 2 3 4 5 Subject 68 A Million Different Implementations class of the application or to a new class. The same is true for the ob-server role. In some situations both roles may even be combined within a single class: a class may be an observer in one relationship, and a subject in another. An observer may receive events from a single subject or from multiple subjects. Similarly, a subject may be observed by a single observer or multiple observers.
  • Book cover image for: Beginning Java Programming
    eBook - ePub

    Beginning Java Programming

    The Object-Oriented Approach

    • Bart Baesens, Aimee Backiel, Seppe vanden Broucke(Authors)
    • 2015(Publication Date)
    • Wrox
      (Publisher)
    The chain-of-responsibility pattern is somewhat underappreciated in practice. In most cases, you’ll see examples like this one being solved by an implementation of the Observer Pattern (which you’ll see next). However, the chain-of-responsibility pattern is still mentioned here, for two reasons. The first one is that this pattern also defines an order of responsibility. For a logging system, this is not important, but for other systems, it can be useful to establish an ordering, with the first objects in the chain getting a chance to handle the incoming message or object (and potentially modify it) before passing it on. The second reason entails this “passing on” behavior. In most cases where this pattern is useful, you’ll code it in such a way that an object in the chain will only pass on an incoming object when the current link is unable to do anything useful with it. Once a link that can handle the incoming object is found, the processing stops there.
    Observer Pattern and Model-View-Controller Pattern
    The Observer Pattern describes a framework in which a particular object (the subject) maintains a list of dependents (observers) and notifies them of any important changes.
    In Java, this pattern can be implemented in different ways. The first one is by using Java’s built-in java.util.Observable class and the java.util.Observer interface. Observable defines the following methods your classes can override:
    • void addObserver(Observer o)
    • void deleteObserver(Observer o)
    • void deleteObservers()
    • int countObservers()
    • protected void clearChanged()
    • boolean hasChanged()
    • void notifyObservers()
    • void notifyObservers(Object arg)
    • protected void setChanged()
    The Observer interface defines only one method—void update(Observable o, Object arg) —which will be called by the subject. This is illustrated with an example. Say you are building an application to fetch stock quotes. At one point, you realize that other applications might want to plug in to your code to register an interest to be notified whenever you pull in a new stock quote. You decide to make the relevant class in your code Observable :
    import java.util.Observable; // Observable class (the subject) public class StockTicker extends Observable { public void updateStock() { // Stock retrieving code here // At the end, we get a Quote object, which we pass to our observers Quote latestStockQuote = ...; notifyObservers(latestStockQuote); } }
    Note the notifyObservers
  • Book cover image for: Python Object-Oriented Programming
    eBook - ePub

    Python Object-Oriented Programming

    Build robust and maintainable object-oriented Python applications and libraries, 4th Edition

    • Steven F. Lott, Dusty Phillips(Authors)
    • 2021(Publication Date)
    • Packt Publishing
      (Publisher)
    Whenever a value on the core object changes, it lets all the observer objects know that a change has occurred, by calling a method announcing there's been a change of state. This is used widely in GUIs to make sure that any state change in the underlying model is reflected in the views of the model. It's common to have detail and summary views; a change to the details must also update the widgets that display the details and update any summaries that are displayed, also. Sometimes a large change in mode may lead to a number of items being changed. For instance, clicking a "lock" icon may alter a number of displayed items to reflect their status as locked. This can be implemented as a number of observers attached to the observable display widget.
    In Python, the observer can be notified via the __call__() method, making each observer behave like a function or other callable object. Each observer may be responsible for different tasks whenever the core object changes; the core object doesn't know or care what those tasks are, and the observers don't typically know or care what other observers are doing.
    This allows tremendous flexibility by decoupling the response to a state change from the change itself. Here is a depiction of the Observer design pattern in UML: Figure 11.3: Observer Pattern in UML
    We've shown the Core object as containing a list of observer objects. To be observable, the Core class must adhere to a common understanding of observability; specifically, it must provide a list of observers and a way to attach new observers.
    We've shown the Observer subclasses as having a __call__() method. This will be used by the observable to notify each observer of a state change. As with the Decorator pattern, we don't need to formalize the relationships with formally defined abstract superclasses. In most cases, we can rely on duck typing rules; as long as the observers have the right interface, they can be used in the defined role in this pattern. If they lack the proper interface, mypy may catch the conflict, and a unit test should catch the problem.

    An Observer example

    Outside a GUI, the Observer Pattern is useful for saving intermediate states of objects. Using observer objects can be handy in systems where a rigorous audit of changes is required. It's also handy in a system where chaos reigns and components are unreliable.
  • Index pages curate the most relevant extracts from our library of academic textbooks. They’ve been created using an in-house natural language model (NLM), each adding context and meaning to key research topics.