最近在学习下设计模式,而加深学习的不错的方法就是把心得写出来吧。记录下自己的理解。现在自己看的书是《head.Frist设计模式》这本书。比较不错,想看的朋友可以看下。
观察者
举个例子,张三从邮局订阅了《南方周末》,李四从邮局订阅了《新京报》,王五从邮局里面订阅了《南方都市报》。当报纸抵达邮局的时候,邮局就会把报纸送递订阅者。而不需要订阅者天天到邮局询问报纸是否到达邮局。
下面开始代码:首先应该是个订阅者接口:
package cn.demo; public interface ISubscribe { //从邮局订阅报纸 public void registered(PostOffice postOffice); //从邮局退订报纸 public void unregistered(PostOffice postOffice); //获取报纸名称 public void getNewsPaper(); }
然后有三个订阅者类:
张三:
package cn.demo; public class ZhangSan implements ISubscribe{ private String mName; private String mNewsPaperName; public ZhangSan(String mName, String mNewsPaperName) { this.mName = mName; this.mNewsPaperName = mNewsPaperName; } public String getName() { return mName; } public String getNewsPaperName() { return mNewsPaperName; } @Override public void registered(PostOffice postOffice){ postOffice.registeredNewsPaper(this); } @Override public void unregistered(PostOffice postOffice){ postOffice.unregisteredNewsPaper(this); } @Override public void getNewsPaper() { // TODO Auto-generated method stub System.out.println("我是"+getName()+",我收到我订阅的"+getNewsPaperName()); } }
package cn.demo; public class Lisi implements ISubscribe{ private String mName; private String mNewsPaperName; public Lisi(String mName, String mNewsPaperName) { this.mName = mName; this.mNewsPaperName = mNewsPaperName; } public String getName() { return mName; } public String getNewsPaperName() { return mNewsPaperName; } @Override public void unregistered(PostOffice postOffice){ postOffice.unregisteredNewsPaper(this); } @Override public void registered(PostOffice postOffice){ postOffice.registeredNewsPaper(this); } @Override public void getNewsPaper() { // TODO Auto-generated method stub System.out.println("我是"+getName()+",我收到我订阅的"+getNewsPaperName()); } }
package cn.demo; public class Wangwu implements ISubscribe{ private String mName; private String mNewsPaperName; public Wangwu(String mName, String mNewsPaperName) { this.mName = mName; this.mNewsPaperName = mNewsPaperName; } public String getName() { return mName; } public String getNewsPaperName() { return mNewsPaperName; } @Override public void registered(PostOffice postOffice){ postOffice.registeredNewsPaper(this); } @Override public void unregistered(PostOffice postOffice){ postOffice.unregisteredNewsPaper(this); } @Override public void getNewsPaper() { // TODO Auto-generated method stub System.out.println("我是"+getName()+",我收到我订阅的"+getNewsPaperName()); } }
三个订阅者,都有方法订阅报纸,或者取消订阅。其实关于订阅者的信息,是存储在邮局类里面。
import java.util.ArrayList; import java.util.List; public class PostOffice { private List在这个类里面,有变化通知是使用的sendNewsPaper()这个方法,遍历所有的订阅者。SubscribeList = new ArrayList (); public void registeredNewsPaper(ISubscribe subscribe) { SubscribeList.add(subscribe); } public void unregisteredNewsPaper(ISubscribe subscribe) { if (subscribe != null) { SubscribeList.remove(subscribe); } } public void getNewsPaper(boolean bool) { if (bool) { sendNewsPaper(); } } public void sendNewsPaper() { for(ISubscribe subscribe : SubscribeList) { subscribe.getNewsPaper(); } } }
public static void main(String[] args) { // TODO Auto-generated method stub PostOffice mPostOffice = new PostOffice(); ISubscribe zhangsan = new ZhangSan("张三", "《南方周末》"); ISubscribe lisi = new Lisi("李四", "《新京报》"); ISubscribe wangwu = new Wangwu("王五", "《南方都市报》"); //开始订阅报纸 zhangsan.registered(mPostOffice); lisi.registered(mPostOffice); wangwu.registered(mPostOffice); //邮局收到报纸,开始发放 mPostOffice.getNewsPaper(true); //李四退订 lisi.unregistered(mPostOffice); //邮局收到报纸,开始发放 mPostOffice.getNewsPaper(true); }
我是张三,我收到我订阅的《南方周末》 我是李四,我收到我订阅的《新京报》 我是王五,我收到我订阅的《南方都市报》 我是张三,我收到我订阅的《南方周末》 我是王五,我收到我订阅的《南方都市报》
这里只是提供了一个简单的例子,而且代码你会发现有冗余,三个订阅者类,几乎是一样,因为没有在类里面添加他们独自的属性,可以用一个Person类来替代。这里写这三个类是为了显示清晰。
在Android中,button.setOnclickListener()这个方式是比较常见的观察者模式:当然,众所周知,onClick是著名的回调方法,在这里不会研究回调,不用太在意。
看下代码:
Button button1 = (Button)findViewById(R.id.button1); Button button2 = (Button)findViewById(R.id.button2); Button button3 = (Button)findViewById(R.id.button3); button1.setOnClickListener(this); button2.setOnClickListener(this); button3.setOnClickListener(this); } @Override public void onClick(View v) { // TODO Auto-generated method stub switch(v.getId()) { case R.id.button1 : // do some thing case R.id.button2 : // do some thing case R.id.button3 : // do some thing } }
public void sendNewsPaper() { for(ISubscribe subscribe : SubscribeList) { subscribe.getNewsPaper(); } }
最后,如果我们的邮局要实现类似button这样的回调这么实现呢?
ISubscribe isubscribe; @Override public void getNewsPaper() { // TODO Auto-generated method stub System.out.println("我是"+getName()+",我收到我订阅的"+getNewsPaperName()); isubscribe.getNewsPaper(); }