Android观察者模式

17 篇文章 1 订阅
6 篇文章 4 订阅
一、简述:

    生活中的观察者模式:    
    还记得警匪片上,匪徒们是怎么配合实施犯罪的吗?一个团伙在进行盗窃的时候,总有一两个人在门口把风——如果有什么风吹草动,则会立即通知里面的同伙紧急撤退。也许放风的人并不一定认识里面的每一个同伙;而在里面也许有新来的小弟不认识这个放风的。但是这没什么,这个影响不了他们之间的通讯,因为他们之间有早已商定好的暗号。
呵呵,上面提到的放风者、偷窃者之间的关系就是观察者模式在现实中的活生生的例子。
    观察者模式简介:
    观察者(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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值