Introduction to Design Patterns--Observer Pattern

concept

When the state of a subject object changes, it will automatically notify its dependent objects to perform some logical processing, which is the observer pattern.
To put it bluntly, a class depends on another or even multiple classes. When the state of this class instance changes, it will call the interface of the object it depends on, triggering it to rely on the object to perform some logic processing. It feels very abstract to take it out. In fact, this design pattern is often used in our code.


Role

  • Abstract subject: the observed (Subject). Provides operation interfaces for adding, deleting, and notifying observers.

  • Specific subject: The specific observed. Internally provides a container for observer registration, and each observer can have any number of observers. When the subject object changes, it will notify the observer object registered in the container of the change.

  • Abstract Observer: Observer is an abstract class or interface of a specific observer, which defines a specific logical processing method, so that some logical processing is performed when a subject change notification is received.

  • Concrete Observer: The concrete implementation class of the abstract observer.

The meaning of abstract subject and abstract observer: use the polymorphism feature of java to reduce the coupling between concrete classes and concrete classes.


specific code

1. com.learn.observerpattern.way1 ( using the example of the big guy )

Scenario: Assume that WeChat users are the observers, and the WeChat official account is the observed person. There are multiple WeChat users who follow a certain official account. When the official account is updated, these subscribed WeChat users will be notified.

abstract theme

package com.learn.observerpattern.way1;

/**
 * 抽象被观察者(Subject)抽象主题对象
 * Created by chao.du on 2018/2/1.
 */
public interface ISubject {
    /**
     * 增加订阅者
     * @param observer
     */
    void addObserver(IObserver observer);
    /**
     * 删除订阅者
     * @param observer
     */
    void delObserver(IObserver observer);
    /**
     * 通知订阅者更新消息
     */
    void notifyObserver();

    /**
     * 更新状态
     */
    void updateState(String state);
}

specific subject

package com.learn.observerpattern.way1;

import java.util.ArrayList;
import java.util.List;

/**
 * 具体主题,被观察者具体实现类
 * Created by chao.du on 2018/2/1.
 */
public class WeixinSubject implements ISubject{

    private String state;
    private List<IObserver> observers=new ArrayList<IObserver>();

    public void addObserver(IObserver observer) {
        this.observers.add(observer);
    }

    public void delObserver(IObserver observer) {
        this.observers.remove(observer);
    }

    public void notifyObserver() {
        for (IObserver observer:observers){
            observer.update(this.state);
        }
    }

    public void updateState(String state) {
        this.state=state;
        this.notifyObserver();
    }
}

abstract observation

package com.learn.observerpattern.way1;

/**
 * 观察者接口
 * Created by chao.du on 2018/2/1.
 */
public interface IObserver {
    public void update(String message);
}

specific observer

package com.learn.observerpattern.way1;

/**
 * 观察者接口具体观察实现者
 * Created by chao.du on 2018/2/1.
 */
public class WeixinUser implements IObserver {

    private String name;

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

    public void update(String message) {
        System.out.println(this.name+"收到了一个通知--"+message);
    }
}

client

package com.learn.observerpattern.way1;

/**
 * 测试客户端
 * Created by chao.du on 2018/2/1.
 */
public class Client {

    public static void main(String[] args) {
        //创建微信订阅主题
        ISubject subject=new WeixinSubject();
        //给主题添加订阅者
        subject.addObserver(new WeixinUser("小明"));
        subject.addObserver(new WeixinUser("小花"));
        subject.addObserver(new WeixinUser("小美"));
        //主题更新,通知订阅者
        subject.updateState("XX微信公众号发布了一篇新文章《如何与dalao同归于尽》");
    }

}

Test Results
write picture description here

2、com.learn.observerpattern.way2

Scenario: The news website pushes news to registered users every day. The abstract subject is the information website, and the observed person is the registered user.

abstract theme

package com.learn.observerpattern.way2;

/**
 * 抽象主题
 * Created by chao.du on 2018/2/1.
 */
public interface ISubject {

    /**
     * 注册/添加观察者
     * @param observer
     */
    void addObserver(IObserver observer);

    /**
     * 更新主题对象消息状态
     * @param isGood
     * @param message
     */
    void updateMessage(boolean isGood,String message);

    /**
     * 通知观察者
     * @param isGood
     */
    void notiryObserver(boolean isGood);

}

specific subject

package com.learn.observerpattern.way2;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 具体主题,具体被观察者
 * Created by chao.du on 2018/2/1.
 */
public class RealSubject implements ISubject {

    /**
     * 消息
     */
    private String message;

    /**
     * 观察者容器
     */
    private List<IObserver> observerList=new ArrayList<IObserver>();

    /**
     * 添加观察者
     * @param observer
     */
    public void addObserver(IObserver observer){
        this.observerList.add(observer);
    }

    /**
     * 更新主题对象消息,通知观察者
     * @param isGood
     * @param message
     */
    public void updateMessage(boolean isGood,String message) {
        this.message=message;
        this.notiryObserver(isGood);
    }

    /**
     * 通知对象,把Message消息对象发送给
     * @param isGood true好消息 false坏消息
     */
    public void notiryObserver(boolean isGood) {
        HashMap<String,Object> content=new HashMap<String, Object>();
        content.put("message",this.message);
        for (IObserver observer:observerList) {
            if(isGood){
                observer.getWeiXinInfo(new Message(Message.MessageType.GOOD,content));
            }else{
                observer.getWeiXinInfo(new Message(Message.MessageType.BAD,content));
            }
        }
    }
}

abstract observer

package com.learn.observerpattern.way2;

/**
 * 抽象观察者
 * Created by chao.du on 2018/2/1.
 */
public interface IObserver {

    void getWeiXinInfo(Message message);
}

Concrete Observer 1

package com.learn.observerpattern.way2;

/**
 * 具体观察者
 * Created by chao.du on 2018/2/1.
 */
public class RealObserver1 implements IObserver{

    private String name;

    public RealObserver1(String name, ISubject weiXinSubject) {
        this.name=name;
        weiXinSubject.addObserver(this);
    }

    public void getWeiXinInfo(Message message) {
        System.out.println(this.name+"收到一个"+message.getType().getInfoTip()+"----"+message.getContent().get("message"));
    }
}

Concrete Observer 2

package com.learn.observerpattern.way2;


/**
 * 具体观察者
 * Created by chao.du on 2018/2/1.
 */
public class RealObserver2 implements IObserver{

    private String name;

    public RealObserver2(String name, ISubject weiXinSubject) {
        this.name=name;
        weiXinSubject.addObserver(this);
    }

    public void getWeiXinInfo(Message message) {
        System.out.println(this.name+"收到一个"+message.getType().getInfoTip()+"----"+message.getContent().get("message"));
    }
}

Concrete Observer 3

package com.learn.observerpattern.way2;

/**
 * 具体观察者
 * Created by chao.du on 2018/2/1.
 */
public class RealObserver3 implements IObserver{

    private String name;

    public RealObserver3(String name, ISubject weiXinSubject) {
        this.name=name;
        weiXinSubject.addObserver(this);
    }

    public void getWeiXinInfo(Message message) {
        System.out.println(this.name+"收到一个"+message.getType().getInfoTip()+"----"+message.getContent().get("message"));
    }
}

notification message entity

package com.learn.observerpattern.way2;

import java.util.Map;

/**
 * 通知消息实体封装
 * Created by chao.du on 2018/2/1.
 */
public class Message {

    private  MessageType type;

    private Map<String,Object> content;

    public Message(MessageType type, Map<String, Object> content) {
        this.type = type;
        this.content = content;
    }

    public MessageType getType() {
        return type;
    }

    public void setType(MessageType type) {
        this.type = type;
    }

    public Map<String, Object> getContent() {
        return content;
    }

    public void setContent(Map<String, Object> content) {
        this.content = content;
    }

    enum  MessageType{

        GOOD(true,"好消息"),BAD(false,"坏消息");

        private final boolean infoState;
        private final String infoTip;

        MessageType(boolean infoState,String infoTip){
            this.infoState=infoState;
            this.infoTip=infoTip;
        }

        public boolean getInfoState() {
            return infoState;
        }

        public String getInfoTip() {
            return infoTip;
        }
    }
}

client

package com.learn.observerpattern.way2;

/**
 * 客户端,测试
 * Created by chao.du on 2018/2/1.
 */
public class Client {
    public static void main(String[] args) {
        //创建主题
        ISubject subject=new RealSubject();
        //创建观察者,并放入主题集合
        new RealObserver1("农民",subject);
        new RealObserver2("教师",subject);
        new RealObserver3("工人",subject);
        //主题修改,通知观察者
        subject.updateMessage(true,"还有几天要放年假了!!!");
        System.out.println("----------------------------------");
        subject.updateMessage(false,"过完年房价要涨了!!!");
    }
}

Test Results
write picture description here

github code


References:
1. "Design Patterns (3): The Difference Between Observer Patterns and Publish/Subscribe Patterns"
2. "Observer Patterns"
3. "Design Patterns (5) Observer Patterns"

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325772040&siteId=291194637