观察者模式
来源:互联网 发布:imovie的windows版 编辑:程序博客网 时间:2024/06/06 01:12
观察者模式示例
抽象主题(Subject):它把所有观察者对象的引用保存到一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。
具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。
具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。
1.Subject 和 Observer 是一个一对多的关系,也就是说观察者只要实现 Observer 接口并把自己注册到 Subject 中就能够接收到消息事件;
2.Java API有内置的观察者模式类:Java.util.Observable 类和 java.util.Observer 接口,这分别对应着 Subject 和 Observer 的角色;
3.使用 java API 的观察者模式类,需要注意的是被观察者在调用 notifyObservers() 函数通知观察者之前一定要调用 setChanged() 函数,要不然观察者无法接到通知;
4.使用 Java API 的缺点也很明显,由于 Observable 是一个类,java 只允许单继承的缺点就导致你如果同时想要获取另一个父类的属性时,你只能选择适配器模式或者是内部类的方式,而且由于 setChanged() 函数为 protected 属性,所以你除非继承 Observable 类,否则你根本无法使用该类的属性,这也违背了设计模式的原则:多用组合,少用继承。
1、被观察者:
public class PassiveObserver extends Observable { private String name; private String id; public String getName() { return name; } public void setName(String name) { this.name = name; setChanged(); //没有这两个方法观察者收不到通知 notifyObservers(); } public String getId() { return id; } public void setId(String id) { this.id = id; setChanged(); notifyObservers(); }}
public class MObserver implements Observer { private static final String TAG = MObserver.class.getSimpleName(); private int id; private String name; private PassiveObserver passiveObserver; public MObserver(int id,String name) { this.id = id; this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getId() { return id; } public void setId(int id) { this.id = id; } public PassiveObserver getPassiveObserver() { return passiveObserver; } public void setPassiveObserver(PassiveObserver passiveObserver) { this.passiveObserver = passiveObserver; } @Override public void update(Observable observable, Object data) { this.passiveObserver = (PassiveObserver) observable; }}
3、MainActivity
public class MainActivity extends Activity { private static final String TAG = MainActivity.class.getSimpleName(); private int i; private int j; private PassiveObserver pObserver; private ArrayList<MObserver> mObservers; private ListView lv; private Button btn; private MObserver mObserver; private MyListAdapter adapter; private Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { Log.e(TAG, "handleMessage: " + i + " ---- " + mObservers.get(0).getPassiveObserver()); adapter.setData(mObservers); lv.setAdapter(adapter); }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initViews(); initData(); dataChange(); //点击增加观察者 btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { j++; MObserver mObserver = new MObserver(10000 + j,"新加的观察者10000" + j); pObserver.addObserver(mObserver); mObservers.add(mObserver); } }); } private void initData() { mObservers = new ArrayList<>(); pObserver = new PassiveObserver(); for (int z = 0; z < 3; z++) { mObserver = new MObserver(z,"观察者" + z); mObservers.add(mObserver); pObserver.addObserver(mObserver); } adapter.setData(mObservers); lv.setAdapter(adapter); } //观察者数据变化 private void dataChange() { handler.postDelayed(new Runnable() { @Override public void run() { pObserver.setName("我是被观察者"); pObserver.setId("被观察者变化的id" + i++); handler.sendEmptyMessage(0); dataChange(); } },1000); } private void initViews() { lv = ((ListView) findViewById(R.id.lv)); btn = ((Button) findViewById(R.id.btn)); adapter = new MyListAdapter(this); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); pObserver.deleteObserver(mObserver); }}
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- 观察者模式
- java知识点一
- SpringMVC在Controller层中注入request的坑
- Codeforces Gym 101164 G. Pokemons
- .NET体系
- jqgrid--rownumbers添加标题头
- 观察者模式
- POJ-1276 多重背包问题
- Android引导页消失进入软件
- Codeforces Gym 101164 H. Pub crawl (凸包)
- 【剑指offer】题45:圆圈中最后剩下的数字
- java.util.HashMap
- 归并排序
- Codeforces Gym 101164 K. Cutting (字符串 HASH)
- V4L2常用命令详解