您当前的位置: 首页 > 
  • 0浏览

    0关注

    674博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

观察者模式实践

沙漠一只雕得儿得儿 发布时间:2019-03-13 20:22:33 ,浏览量:0

这个模式的定义:

定义对象间的一种一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都能得到通知并被自动更新

使用场景如下:

  1. 有一种短信服务,比如天气预报服务,一旦你订阅该服务,你只需按月付费,付完费后,每天一旦有天气信息更新,它就会及时向你发送最新的天气信息。
  2. 杂志的订阅,你只需向邮局订阅杂志,缴纳一定的费用,当有新的杂志时,邮局会自动将杂志送至你预留的地址。

观察上面两个情景,有一个共同点,就是我们无需每时每刻关注我们感兴趣的东西,我们只需做的就是订阅感兴趣的事物,比如天气预报服务,杂志等,一旦我们订阅的事物发生变化,比如有新的天气预报信息,新的杂志等,被订阅的事物就会即时通知到订阅者,即我们。而这些被订阅的事物可以拥有多个订阅者,也就是一对多的关系。当然,严格意义上讲,这个一对多可以包含一对一,因为一对一是一对多的特例,没有特殊说明,本文的一对多包含了一对一。

然后我们看一下观察者模式的几个重要组成。

  • 观察者,我们称它为Observer,有时候我们也称它为订阅者,即Subscriber
  • 被观察者,我们称它为Observable,即可以被观察的东西,有时候还会称之为主题,即Subject

在观察者模式中有如下角色。

• Subject:抽象主题(抽象被观察者)。抽象主题角色把所有观察者对象保存在一个集合里,每个主题
都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
• ConcreteSubject:具体主题(具体被观察者)。该角色将有关状态存入具体观察者对象,在具体主题
的内部状态发生改变时,给所有注册过的观察者发送通知。
• Observer:抽象观察者,是观察者的抽象类。它定义了一个更新接口,使得在得到主题更改通知时更
新自己。
• ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新
自身的状态。

下面是我们的实例运行:

一个按钮订阅一个观察者,发布消息后,订阅过的即可接收到消息:

 

具体实现:

1.一个抽象主题(被观察者Subject)
public interface Subject {
    void addObserver(Observer observer);
    void notifyObserver(MessageBean message);
    void removeObserver(Observer observer);
    void clearObserver();
}
2.抽象主题的具体实现类(ConcreteSSubject)
public class ConcreteSubject implements Subject {

    private List userList = new ArrayList();

    private static ConcreteSubject instance = new ConcreteSubject();
    public ConcreteSubject(){}
    public static ConcreteSubject getInstance() {
        return  instance;
    }

    @Override
    public void addObserver(Observer observer) {
        userList.add(observer);
        Log.d("########",userList.size() +"");
    }

    @Override
    public void notifyObserver(MessageBean message) {
        for (Observer observer : userList) {
            observer.update(message);
        }
    }

    @Override
    public void removeObserver(Observer observer) {
        userList.remove(observer);
    }

    @Override
    public void clearObserver() {
        userList.clear();
    }
}
3.抽象观察者(Observer)
public interface Observer {
    void update(MessageBean message);
}
4.抽象观察者的实现类(ConcreteObserver)
1.自己的类中需要implement Observer

2.
@Override
    public void update(MessageBean message) {
        if (message.getFromOne() == true) {
            txt1.setText(message.getMessage());
        }
        if (message.getFromTwo() == true) {
            txt2.setText(message.getMessage());
        }
        if (messageBean.getFromOne() == true && messageBean.getFromTwo() == true) {
            txt1.setText(message.getMessage());
            txt2.setText(message.getMessage());
        }

    }
5.使用类(和第四步抽象观察者的实现类是一个地方)
public class MainActivity extends AppCompatActivity implements View.OnClickListener, Observer {

    Button btn1;
    Button btn2;
    TextView txt1;
    TextView txt2;
    Button notifyBtn;
    Button cancelBtn;

    ConcreteObserver observer1;
    ConcreteObserver observer2;
    Subject subject;

    int messageNumber = 1;
    StringBuilder message = new StringBuilder("发送消息");
    MessageBean messageBean = new MessageBean();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btn1 = findViewById(R.id.observer1);
        btn2 = findViewById(R.id.observer2);
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);

        txt1 = findViewById(R.id.text1);
        txt2 = findViewById(R.id.text2);

        notifyBtn = findViewById(R.id.subject);
        notifyBtn.setOnClickListener(this);

        cancelBtn = findViewById(R.id.remove_subject);
        cancelBtn.setOnClickListener(this);

        observer1 = new ConcreteObserver();
        observer2 = new ConcreteObserver();
        subject = new ConcreteSubject();
    }

    @Override
    public void onClick(View v) {

        int id = v.getId();
        if (id == R.id.observer1) {
//            subject.addObserver(observer1);
            messageBean.setFromOne(true);
            ConcreteSubject.getInstance().addObserver(this);
        } else if (id == R.id.observer2) {
//            subject.addObserver(observer2);
            messageBean.setFromTwo(true);
            ConcreteSubject.getInstance().addObserver(this);
        } else if (id == R.id.subject) {
//            subject.notifyObserver(messageBean);
            messageBean.setMessage(message.append(messageNumber++) + "");
            ConcreteSubject.getInstance().notifyObserver(messageBean);
        } else if (id == R.id.remove_subject) {
            messageBean.setFromOne(false);
            messageBean.setFromTwo(false);
            ConcreteSubject.getInstance().clearObserver();
        }
    }

    @Override
    public void update(MessageBean message) {
        if (message.getFromOne() == true) {
            txt1.setText(message.getMessage());
        }
        if (message.getFromTwo() == true) {
            txt2.setText(message.getMessage());
        }
        if (messageBean.getFromOne() == true && messageBean.getFromTwo() == true) {
            txt1.setText(message.getMessage());
            txt2.setText(message.getMessage());
        }

    }
}
以上就是一个观察者模式的具体实现,其中的MessageBean实体类和布局文件如下:
public class MessageBean {

    boolean fromOne;
    boolean fromTwo;
    String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public boolean getFromOne() {
        return fromOne;
    }

    public void setFromOne(boolean fromOne) {
        this.fromOne = fromOne;
    }

    public boolean getFromTwo() {
        return fromTwo;
    }

    public void setFromTwo(boolean fromTwo) {
        this.fromTwo = fromTwo;
    }
}



    

        

        

    

    

        

        

    

    

    

整个项目实例:https://github.com/buder-cp/base_component_learn/tree/master/observermodel

关注
打赏
1657159701
查看更多评论
立即登录/注册

微信扫码登录

0.0401s