1.观察者模式创建步骤 1.目标(被观察者)对象的定义 2.具体目标对象的定义 3.观察者接口的定义 4.观察者的具体实现 2.观察者的两种实现方式:推模型 和 拉模型 推模型: 目标对象主动向观察者推送目标得的详细信息 推送的信息通常是目标对象的全部或者部分数据 拉模型: 目标对象再通知观察者时,只传递少量信息 如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于是观察者从目标对象中啦数据; 一般这种模型的实现,会把目标对象通过update方法传递给观察者 3.比较两种模型 推模型会使观察者对象难以复用 拉模型:update方法的参数目标对象本身,基本上可以适用各种情况的需要 4.Java实现与自己实现的对比 1.不需要在定义观察者和目标的接口了,JDK已经实现了 2.具体的目标实现里不需要在维护观察者的注册信息了,因为Java中的Observable类里面已经实现了; 3.触发通知的方式有一点变化,要先调用setChange方法,这是Java为了实现更加精确的触发功能而提供的功能 4.具体观察者的实现里,update方法其实能同时支持推模型和拉模型。 5.观察者优缺点 优点: 1.观察者实现了观察者和目标之间的抽象耦合 2.观察者模式实现动态的联动 3.观察者模式支持广播的发送 缺点: 1.可能会引起无谓的操作 6.观察者实现代码示例: 1)观察者模式目标对象的创建2)观察者接口创建/* 拉模型的实现 * 目标对象,该对象知道观察他的观察者,并提供注册(添加) 和删除观察者的接口 * */ public class Subject { // 用来保存被注册的观察者对象 private List<Observer> mObservers = new ArrayList<>(); // 添加注册的观察者 public void attach(Observer observer){ mObservers.add(observer); } //删除注册的观察者 public void detach(Observer observer){ mObservers.remove(observer); } //更新观察者的数据 protected void notifyObserver(){ for (Observer observer : mObservers){ observer.update(this); } } }
3)继承目标类(即被观察者)实现实体目标类/* * 创建观察者接口,定义一个更新的接口实时更新观察者的数据 * */ public interface Observer { void update(Subject subject); }
/* * 具体的目标对象 负责把数据信息存入到相应的观察者对象中 * */ public class EntrySubject extends Subject { // 目标对象的状态 private String subjectStates; public String getSubjectStates() { return subjectStates; } public void setSubjectStates(String subjectStates) { this.subjectStates = subjectStates; this.notifyObserver(); } }
4)实现观察者接口,创建实体观察者类public class EntryObserver implements Observer { // 观察者状态 private String observerStatus; private static final String TAG = "EntryObserver"; // 设置观察者做出的反应 private String feel; public String getFeel() { return feel; } public void setFeel(String feel) { this.feel = feel; } @Override public void update(Subject subject) { observerStatus = ((EntrySubject) subject).getSubjectStates(); Log.d(TAG, "SubjectStatus is " + observerStatus +", ObserverFeel"+ feel); } }
5)主线程中观察者订阅目标对象(被观察者)
// 1.创建目标(被观察者) EntrySubject subject = new EntrySubject(); // 2. 创建观察者 EntryObserver observer = new EntryObserver(); observer.setFeel("haha"); EntryObserver observer1 = new EntryObserver(); observer1.setFeel("hei hei"); // 3.注册观察者 subject.attach(observer); subject.attach(observer1); // 4.发布消息 subject.setSubjectStates("hello world");
7.Java中的API自带的观察者调用代码示例
1)继承Java中的Observable类来创建目标类2)继承Java中的Observer类来实现观察者类public class JavaOfSubject extends Observable{ private String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; this.setChanged();//该方法必须调用 //主动通知,推模式 this.notifyObservers(content); // 拉模式 调用下面方法 //this.notifyObservers(); } }
3)主线程中观察者订阅目标对象(被观察者)/* * Java下的Observer观察者 * */ public class JavaOfObserver implements Observer { private String ObserverName; private static final String TAG = "JavaOfObserver"; @Override public void update(Observable o, Object arg) { // 方式一:推模式 Log.d(TAG,ObserverName + " 收到消息,目标发来的信息是" + arg); // 方式二:拉模式 Log.d(TAG, ObserverName + "收到消息,主动到目标对象中去拉,拉的内容就是" + ((JavaOfSubject) o).getContent()); } public String getObserverName() { return ObserverName; } public void setObserverName(String observerName) { ObserverName = observerName; } }
//创建目标对象(被观察者) JavaOfSubject subject = new JavaOfSubject(); // 创建观察者 JavaOfObserver observer = new JavaOfObserver(); observer.setObserverName("张三"); JavaOfObserver observer1 = new JavaOfObserver(); observer1.setObserverName("李四"); // 注册观察者 subject.addObserver(observer); subject.addObserver(observer1); // 更新目标数据 subject.setContent("你们好呀!");
8.观察者示例展示
// 该接口是给目标发生改变时被通知的观察者对象调用 public interface Observer { // 更新的接口方法 void update(WeatherSubject subject); // 设置观察者名称 void setObserverName(String observerName); // 取得观察者名称 public String getObserverName(); }
public abstract class WeatherSubject { //用来保存注册观察者对象 public List<Observer> mObservers = new ArrayList<>(); // 用来添加订阅目标对象的观察者 public void attach(Observer observer){ mObservers.add(observer); } // 删除集合中订阅目标对象的观察者 public void detach(Observer observer){ mObservers.remove(observer); } protected abstract void notifyObservers(); }
public class EntryWeatherObserver implements Observer{ private static final String TAG = "Weather"; private String observerName; // 天气的情况的内容 private String weatherContent; //提醒的内容 private String remindThing; public String getRemindThing() { return remindThing; } public void setRemindThing(String remindThing) { this.remindThing = remindThing; } @Override public void update(WeatherSubject subject) { weatherContent = ((EntryWeatherSubject) subject).getWeatherContent(); Log.d(TAG, observerName + "收到了" + weatherContent+"," + remindThing); } @Override public void setObserverName(String observerName) { this.observerName = observerName; } @Override public String getObserverName() { return observerName; } }
主线程中观察者订阅目标public class EntryWeatherSubject extends WeatherSubject { private String weatherContent; @Override protected void notifyObservers() { // 循环所有的注册的观察者 for (Observer observer : mObservers) { // 规则是: // 张三 需要“下雨” 条件通知 其他条件不通知 // 李四 需要 "下雨" 或者“下雪” 的条件通知其他条件不通知 if ("下雨".equals(this.getWeatherContent())){ if ("张三".equals(observer.getObserverName())){ observer.update(this); } if ("李四".equals(observer.getObserverName())){ observer.update(this); } } //如果天气是下雪 if ("下雪".equals(this.getWeatherContent())){ if ("李四".equals(observer.getObserverName())) observer.update(this); } } } public String getWeatherContent() { return weatherContent; } public void setWeatherContent(String weatherContent) { this.weatherContent = weatherContent; this.notifyObservers(); } }
// 1.创建目标 EntryWeatherSubject subject = new EntryWeatherSubject(); //2. 创建观察者 EntryWeatherObserver ZhanSan = new EntryWeatherObserver(); ZhanSan.setObserverName("张三"); ZhanSan.setRemindThing("天要下雨了"); EntryWeatherObserver LiSi = new EntryWeatherObserver(); LiSi.setObserverName("李四"); LiSi.setRemindThing("明天雨夹雪"); // 3.注册观察者 subject.attach(ZhanSan); subject.attach(LiSi); // 4.目标发布天气了 subject.setWeatherContent("下雪");
设计模式之观察者模式
最新推荐文章于 2024-11-02 14:41:55 发布