Code Monkey home page Code Monkey logo

java-mod-3-observer's Introduction

Observer

Learning Goals

  • Explain the observer pattern
  • Use the pattern in Java

Introduction

Here's when you would want to use the pattern:

  • Use to model an object hierarchy where changes to one object, called the subject or the observed, should have an impact on other objects, called the observers, but you don't know ahead of time who these observers are.
  • You also don't want to make assumptions about the observers, i.e. you don't want to have your subject tightly coupled with your observers.

Let's add a checkIn() method to our HotelRoom class. Note that we don't add it to our HotelRoomInterface because this action does not apply to floors - each room has to be checked in individually and by a different person:

class HotelRoom implements HotelRoomInterface {
    public void book(String guestName) {
        Logger.getInstance().log("Booked a room for " + guestName);
    }

    public void clean() {
        Logger.getInstance().log("Cleaned room");
    }

    public void checkIn(String guestName) {
        Logger.getInstance().log(guestName + "checked in");
    }
}

When a guest checks in for a specific room, there are actions that the room must take, which we would implement in the checkIn() method of the HotelRoom class, where that functionality belongs. We may, for example, want to add the room to the cleaning schedule so that the cleaning staff knows to include it in their daily service.

There may, however, be other functionality that should be triggered when a room is booked, but that the room class itself either shouldn't be responsible for implementing or couldn't be responsible for implementing it because that functionality didn't exist when the HotelRoom class was first created. Let's say, for example, that we want to send a welcome email and grant loyalty points to a guest when they check in.

  • welcome email
  • add guest to mobile app push notifications for local events

We could add logic to perform these actions to the checkIn() method, but that would require that the HotelRoom class now be explicitly aware of an email system and a mobile app push notification system, neither of which should be responsibilities of the hotel room itself. Our hotel room should be responsible for its own actions, and then notify other entities that some things have changed and let those other entities decide for themselves what to do about those changes.

In order to make this possible, we need to:

  • Create an interface called RoomCheckinObserver that every class that's interested in the room check-in events will implement. This will allow us to manage any observers no matter their actual class, as long as they implement this interface.
  • Add methods to the HotelRoom class to add/remove observers
  • Add logic to the checkIn() method to notify all the registered observers
  • Add logic to the HotelManager class, where the hotel rooms are created, to add the appropriate observers for each room
  • Create a HotelEmailService class that implements the RoomCheckinObserver interface
  • Create a HotelPushNotificationService class that also implements the RoomCheckinObserver interface

First, let's create the RoomCheckinObserver interface:

interface RoomCheckinObserver {
    public void update(Object updateInfo);
}

We then add methods to add/remove observers from a hotel room to the HotelRoom class, and add logic to the checkIn() method to notify all the observers that a check-in just occurred.

class HotelRoom implements HotelRoomInterface {
    private List<RoomCheckinObserver> checkinObservers = new ArrayList<RoomCheckinObserver>();

    public void book(String guestName) {
        Logger.getInstance().log("Booked a room for " + guestName);
    }

    public void clean() {
        Logger.getInstance().log("Cleaned room");
    }

    public void addCheckinObserver(RoomCheckinObserver checkinObserver) {
        checkinObservers.add(checkinObserver);
    }

    public void removeCheckinObserver(RoomCheckinObserver checkinObserver) {
        checkinObservers.remove(checkinObserver);
    }

    public void checkIn(String guestName) {
        Logger.getInstance().log(guestName + "checked in");
        checkinObservers.forEach((checkinObserver -> checkinObserver.update(guestName)));
    }
}

Now any class that wants to be an observer for the room checkin process needs to implement the RoomCheckinObserver interface. For our email and push notification functionality, we create a HotelEmailService and a HotelPushNotificationService class to handle each respectively:

class HotelEmailService implements RoomCheckinObserver {
    public void update(Object guestName) {
        Logger.getInstance().log("Sent email update to " + guestName);
    }
}

class HotelPushNotificationService implements RoomCheckinObserver {
    public void update(Object guestName) {
        Logger.getInstance().log("Registered " + guestName + " for push notification updates");
    }
}

Finally, we need to add the observers to each room when it gets created, so we update our HotelManager class since that's where our hotel rooms are currently being created:

public class HotelManager {
    public static void main(String[] args) {
       public class HotelManager {
          public static void main(String[] args) {
             Logger.getInstance().log("Managing hotel...");

             // create hotel rooms
             List<HotelRoom> hotelRooms = new ArrayList<HotelRoom>();
             // create hotel floors
             // add hotel rooms to hotel floors
             // take actions on rooms and floors and examine your output to ensure you implemented the desired
             // behaviors
             // create hotel email and notification services
             HotelEmailService emailService = new HotelEmailService();
             HotelPushNotificationService notificationService = new HotelPushNotificationService();
             // initialize hotel email and notification services
             // ...
             hotelRooms.forEach((hotelRoom) -> {
                hotelRoom.addCheckinObserver(emailService);
                hotelRoom.addCheckinObserver(notificationService);
             });
          }
       }
    }
}

java-mod-3-observer's People

Contributors

alveem avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Forkers

connereg

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.