This is the 15th day of my participation in the August More Text Challenge.

Design Pattern #6 (Observer Pattern)


Observer model

Description: All the observed are notified when the observed changes.

Requirement: Readers are required to receive the latest reports of the newspaper when it is published.

Based on previous counter examples, design for interfaces and abstract programming.

Go straight this time,

Is case # 1:

Define an interface for the observer.

// Observer interface
 interface  Observer {
     void update(String Data);

     void disObservered(TheSubject subject);

     void doObservered(TheSubject subject);
}
Copy the code

Here’s a question: Why not use abstract classes for abstraction?

Because I don’t know how the observer model works. In real programming, it is entirely possible that the specific Observer is a completely different class, but they both need to update() based on the notifier’s notification, so let them both implement the Observer interface and override the related methods.

Define an observer:

public class Reader implements Observer{
    private String name ;

    public Reader(String name) {
        this.name = name;
    }

    @Override
    public void update(String Data) {
        System.out.println(this.name+"Receive the newspaper and read the latest report :"+Data);
    }

    @Override
    public void disObservered(TheSubject subject) {
        subject.removeObserver(this);
    }

    @Override
    public void doObservered(TheSubject subject) {
        subject.addObserver(this); }}// The observed abstract class
public abstract class TheSubject {
    // List of observers
    protected List<Observer> observerList = new ArrayList<>();
    // Add to the observer list
    public  boolean addObserver(Observer observer){
        return  observerList.add(observer);
    }
    // Remove from observer list
    public  boolean removeObserver(Observer observer){
        return observerList.remove(observer);
    }
    // Change, and inform the observer
    public abstract void setChange(String Data);
    // Update the content for the observer
    public abstract void upDataObserver(String Data);
}
Copy the code

Oh? So why can’t we use interfaces here?

Notice there’s a variable observerList?

Let’s assume that TheSubject is an interface, and if we need a class to be an observed, we’ll let it implement that interface, and we need to define its observerList, observerList, and if every observed needs to redefine its observerList, Also in the implementation of addObserver, removeObserver two methods, these two methods are fixed algorithms. Repeating too much code has a bad taste.

In this case, duplicate code is written in the abstract class TheSubject, which is inherited by the observer.

public class News_pappers extends TheSubject{
    private  String news;

    public String getNews(a) {
        return news;
    }

    @Override
    public void setChange(String Data) {
        this.news ="Latest report:"+ Data;
        System.out.println("Release the latest report:"+Data);
        upDataObserver(Date);
    }

    @Override
    public void upDataObserver(String Data) {
        for(Observer observer : observerList) { observer.update(Data); }}}public class postive {
/ * = = = = = = = = = = = = = = = = client = = = = = = = = = = = = = = = = = = = = = = = = = = = = * /
    public static void main(String[] args) {
        News_pappers newspaper = new News_pappers();
        Reader lili = new Reader("lili");
        Reader mumu = new Reader("mumu");
        Reader shanshan = new Reader("shanshan");

        newspaper.addObserver(lili);
        newspaper.addObserver(mumu);
        newspaper.addObserver(shanshan);

        newspaper.setChange("Big News");

        shanshan.disObservered(newspaper);

        newspaper.setChange("small00000 News");

        News_pappers news_pappers_02 = new News_pappers();
        mumu.doObservered(news_pappers_02);
        news_pappers_02.setChange("Big news"); }}Copy the code

Running results:

UMLClass diagram:

Careful readers may have noticed that the design principles to be followed are:

  • When adding other types of observers, you only need toObserverInterface can; Added the observed inheriting abstract classTheSubjectOk, accord withThe open closed principle.
  • interfaceObserverAnd an abstract classTheSubjectInterdependence, does not involve the relevant specific observer and observed, accord withDependency inversion principle.

In fact, we all know that Android content providers and content observers, broadcast mechanism are a bit of the taste of observer mode.

Finally, summarize the observer model:

  • The observer pattern should be considered when changes to one object require changes to other objects at the same time, and it is not known exactly how many objects need to be changed.
  • When an abstract model has two aspects, one of which depends on the other, the observer pattern encapsulates the two in separate objects so that they can be changed and reused independently.
  • All the observer pattern does is decouple. Make both sides of the coupling dependent on abstraction, not concrete. So that the change in each side doesn’t affect the change in the other side.
  • The observer and the observed can be many-to-many.
  • The observer abstracts as an interface, and the observer abstracts as an abstract class.