Android观察者模式

来源:互联网 发布:淘宝发货通知短信 编辑:程序博客网 时间:2024/05/22 22:16
一、简述:

    生活中的观察者模式:    
    还记得警匪片上,匪徒们是怎么配合实施犯罪的吗?一个团伙在进行盗窃的时候,总有一两个人在门口把风——如果有什么风吹草动,则会立即通知里面的同伙紧急撤退。也许放风的人并不一定认识里面的每一个同伙;而在里面也许有新来的小弟不认识这个放风的。但是这没什么,这个影响不了他们之间的通讯,因为他们之间有早已商定好的暗号。
呵呵,上面提到的放风者、偷窃者之间的关系就是观察者模式在现实中的活生生的例子。
   观察者模式简介:
    观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
    观察者模式完美的将观察者和被观察者分离开来,在模块之间划定了清晰的界限,提高了程序的可维护性和重用性。

二、观察者模式的组成
  ①抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
  ②抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
  ③具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
  ④具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。

三、Android中应用观察者模式实例
    两个Activity之间的通信可以擦用Bundle、接口回调、利用广播的形式,再或者利用系统总线EventBus,那么现在我们还可以利用观察者模式进行通信。本案例的大致是这样:在SecondActivity中监听一个Button是否被触发,其一旦被触发就向观察者发送消息,MainActivity就是一个观察者,当MainActivity接收到消息之后吐司消息内容并更新UI。
效果图如下:
             
            
先来看一下抽象Subject代码:
/** * 类描述:抽象的Subject * Created by lizhenya on 16/1/02. */public interface Subject {    void register(Observer observer);    void unregister(Observer observer);    void notifyData(String message);}

具体的ConcreteSubject代码如下:
/** * 类描述:具体的Subject * Created by lizhenya on 16/1/02. */public class ConcreteSubject implements Subject {    //存储Observer实例的Arraylist    private List<Observer> observers = new ArrayList<>();    private static final Object Mutex = new Object();    private static volatile ConcreteSubject concreteSubject = null;    private ConcreteSubject() {    }    //单例模式    public static ConcreteSubject getDefault() {        if (concreteSubject == null) {            synchronized (Mutex) {                if (concreteSubject == null) {                    concreteSubject = new ConcreteSubject();                }            }        }        return concreteSubject;    }    @Override    public void register(Observer observer) {        observers.add(observer);    }    @Override    public void unregister(Observer observer) {        if (observers.contains(observer)) {            observers.remove(observer);        }    }    @Override    public void notifyData(String message) {        for (Observer observer : observers) {            observer.onDataChangedEvent(message);        }    }}

抽象Observer代码如下:
/** * 类描述:抽象的Observer * Created by lizhenya on 16/1/02. */public interface Observer {    void onDataChangedEvent(String message);}

具体的Observer代码
/** * 实现了Observer接口成为具体的观察者 */public class MainActivity extends Activity implements Observer {    private TextView txt;    private Button btn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //将观察者注册到Subject中        ConcreteSubject.getDefault().register(this);        initViews();    }    /**     * 方法描述:初始化布局组件     */    private void initViews() {        txt = (TextView) findViewById(R.id.txt);        btn = (Button) findViewById(R.id.btn_main);        btn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                Intent intent = new Intent(MainActivity.this,                        SecondActivity.class);                startActivity(intent);            }        });    }    @Override    public void onDataChangedEvent(String message) {        txt.setText(message);        Toast.makeText(MainActivity.this, "MainActivity接到了消息===》" + message, Toast.LENGTH_SHORT).show();    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.e("TAG","反注册");        //反注册        ConcreteSubject.getDefault().unregister(MainActivity.this);    }}

我们队SecondActivity中的Button进行监听,代码如下:
/** * @author lizhenya * @time 2016年1月02日 * @类描述: */public class SecondActivity extends Activity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.second_activity);        initViews();    }    /**     * @方法描述:初始化布局组件     * @author lizhenya     */    private void initViews() {        Button btn = (Button) findViewById(R.id.btn);        btn.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //事件被触发:发布消息                ConcreteSubject.getDefault().notifyData("SecondActivity中的button按钮被触发了!!!!!!");            }        });    }    @Override    protected void onDestroy() {        super.onDestroy();    }}

完整Demo的下载路径:Android观察者模式demo
2 0
原创粉丝点击