什么是观察者模式(Observer)?
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,让他们能够自动更新自己
观察者模式的组成
抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类或接口来实现。
抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
从AWT1.1开始图形系统的事件模型采用观察者模式,因此观察者模式在Java语言中的地位极其重要
在xml解析中的SAX也采用了观察者模式来实现
Java也提供了对观察者模式的内置支持
Observable类用于创建可以观测到你的程序中其他部分的子类。当这种子类的对象发生变化时,观测类被通知。观测类必须实现定义了update(
设计模式中的观察者模式,如果观察者的属性发生变...
observer 父类中增加一个属性,在observer中赋值和判断,这样可能好点
removeobserver在什么地方使用
KVO Objective-C 观察者模式(Observer Pattern)实现 Cocoa Binding 基础观察象某属性发更改观察者象获通知 意思需要给观察象添加任何额外代码能使用 KVO 做 KVO 实现机制 KVO 实现依赖于 Objective-C 强 Runtime Apple 文档简单提 KVO 实现: Automatic key-value observing is implemented using a technique called isa-swizzling... When an observer is registered for an attribute of an object the isa pointer of the observed object is modified, pointing to an intermediate class rather than at the true class ... Apple 文档真笔带唯用信息:观察象 isa 指针指向间类原真类看Apple 并希望暴露 KVO 实现细节要用 runtime 提供深入挖掘所掩盖细节都原形毕露Mike Ash 早 二009 做探究 简单概述 KVO 实现: 观察象新类态创建类继承自该象原本类并重写观察属性 setter 自重写 setter 负责调用原 setter 前通知所观察象值更改象 isa 指针 ( isa 指针告诉 Runtime 系统象类 ) 指向新创建类象神奇变新创建类实例 原间类继承自原本类仅Apple 重写 -class 企图欺骗我类没变原本类更具体信息跑 Mike Ash 篇文章代码能明白再重复 KVO 缺陷 KVO 强没错知道内部实现或许能帮助更使用或错更便调试官实现 KVO 提供 API 实 比能通重写 -observeValueForKeyPath:ofObject:change:context: 获通知想要提供自定义 selector 行;想要传 block 门都没且要处理父类情况 - 父类同监听同象同属性候知道父类消息兴趣虽 context 参数干解决问题 - -addObserver:forKeyPath:options:context: 传进父类知道 context总觉框 API 设计代码写别扭至少至少应该支持 block 吧 少都觉官 KVO 使Mike Ash Key-Value Observing Done Right及获少享讨论KVO Considered Harmful 都 KVO 拿吊打番所实际发 KVO 使用情景并更候用 Delegate 或 NotificationCenter 自实现 KVO 没找理想自手做既我官 API 太满意知道何实现 KVO尝试自手写简易 KVO 玩玩 首先我创建 NSObject Category并文件添加两 API: typedef void(^PGObservingBlock)(id observedObject, NSString *observedKey, id oldValue, id newValue); @interface NSObject (KVO) - (void)PG_addObserver:(NSObject *)observer forKey:(NSString *)key withBlock:(PGObservingBlock)block; - (void)PG_removeObserver:(NSObject *)observer forKey:(NSString *)key; @end 接实现 PG_addObserver:forKey:withBlock: 逻辑并复杂: 检查象类没相应 setter 没抛异; 检查象 isa 指向类 KVO 类新建继承原类类并 isa 指向新建类; 检查象 KVO 类重写没 setter 没添加重写 setter ; 添加观察者 - (void)PG_addObserver:(NSObject *)observer forKey:(NSString *)key withBlock:(PGObservingBlock)block { // Step 一: Throw exception if its class or superclasses doesn't implement the setter SEL setterSelector = NSSelectorFromString(setterForGetter(key)); Method setterMethod = class_getInstanceMethod([self class], setterSelector); if (!setterMethod) { // throw invalid argument exception } Class clazz = object_getClass(self); NSString *clazzName = NSStringFromClass(clazz); // Step 二: Make KVO class if this is first time adding observer and // its class is not an KVO class yet if (![clazzName hasPrefix:kPGKVOClassPrefix]) { clazz = [self makeKvoClassWithOriginalClassName:clazzName]; object_setClass(self, clazz); } // Step 三: Add our kvo setter method if its class (not superclasses) // hasn't implemented the setter if (![self hasSelector:setterSelector]) { const char *types = method_getTypeEncoding(setterMethod); class_addMethod(clazz, setterSelector, (IMP)kvo_setter, types); } // Step 四: Add this observation info to saved observation objects PGObservationInfo *info = [[PGObservationInfo alloc] initWithObserver:observer Key:key block:block]; NSMutableArray *observers = objc_getAssociatedObject(self, (__bridge const void *)(kPGKVOAssociatedObservers)); if (!observers) { observers = [NSMutableArray array]; objc_setAssociatedObject(self, (__bridge const void *)(kPGKVOAssociatedObservers), observers, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } [observers addObject:info]; } 附处链接:中国至美.cocoachina中国/ios/二0一50三一三/一一三二一.htm
JAVA观察者模式(observer pattern)
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;
public class InfoCenter {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Random rand = new Random();
InfoCenter infoc = new InfoCenter();
Observer1 o1 = new Observer1();
o1.name="sh";
o1.stockSet.add("sgjh");
observerSet.add(o1);
for(int i=0;i<3;i++){
StockChange sc = new StockChange();
sc.put("sgjh",rand.nextFloat());
infoc.SubjectMap.put("sgjh",sc );
sc.change("sgjh", rand.nextFloat());
}
}
public static Set<IObserver> observerSet = new HashSet<IObserver>();
public static Map<String,StockChange<String, Float>> SubjectMap = new HashMap<String,StockChange<String, Float>>();
public static void change(Object key, Object value){
for(IObserver observer:observerSet){
if(observer.contain(key)){
observer.notice(key, value);
//SubjectMap.get(key).change(key, value);
}
}
}
}
class Stock {
String symbol;
Float price;
}
interface IObserver{
void notice(Object key, Object value);
boolean contain(Object key);
}
class Observer1 implements IObserver{
public static Set<String> stockSet = new HashSet<String>();
public String name;
public void notice(Object key, Object value){
if(stockSet.contains(key)){
System.out.println("name="+name+":key="+key+":"+value);}
}
@Override
public boolean contain(Object key) {
return stockSet.contains(key);
}
}
@SuppressWarnings("hiding")
class StockChange<String, Float> extends HashMap<String, Float> {
private static final long serialVersionUID = -8239757303194985716L;
private InfoCenter infoc;
StockChange() {
super();
}
public StockChange(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
}
public StockChange(int initialCapacity) {
super(initialCapacity);
}
public StockChange(Map<? extends String, ? extends Float> m) {
super(m);
}
public void change(String key, Float val) {
Float v1 = get(key);
if ((v1!=null&&val!=null&&!v1.equals(val))||!(v1==null&&val==null)) {
InfoCenter.change(key, val);
put(key, val);
}
}
}
android的FileObserver(文件观察者)不响应啊啊啊...
代码贴一下。
我怀疑你的FileObserver根本就没有启动。