我在把我项目的回调机制改成系统的observer的时候,发现一个问题,大概整理后原型如下: import java.util.Observable; import java.util.Observer;class House extends Observable { int price; public void setPrice(int price) { super.setChanged(); super.notifyObservers(price); this.price = price; }}class HouseObserver implements Observer { @Override public void update(Observable o, Object arg) { System.out.println(o); System.out.println(arg); } }public class test { public static void main(String[] args) { House h = new House(); HouseObserver ho = new HouseObserver(); h.addObserver(ho); h.setPrice(1000); } } 现在的问题是,我要在setPrice()里加多一个参数.在update()里怎么得到area的值.class House extends Observable { int price; public void setPrice(int price,int area) { super.setChanged(); super.notifyObservers(price); this.price = price; }}class HouseObserver implements Observer { @Override public void update(Observable o, Object arg) { System.out.println(o); System.out.println(arg); //如何得到area的值 } }public class test { public static void main(String[] args) { House h = new House(); HouseObserver ho = new HouseObserver(); h.addObserver(ho); h.setPrice(1000,5); } }
哈刚睡醒 package com.meran.normalTest; import java.util.Observable; import java.util.Observer; class House extends Observable { int area; int price; public void setPrice(int price,int area) { this.price = price; this.area=area; super.setChanged(); super.notifyObservers();
} public int getPrice(){ return price; }; public int getArea(){ return area; } } class HouseObserver implements Observer { @Override public void update(Observable o, Object arg) { System.out.println("price"+((House) o).getPrice()); System.out.println("area"+((House)o).getArea()); } } public class test { public static void main(String[] args) { House h = new House(); HouseObserver ho = new HouseObserver(); h.addObserver(ho); h.setPrice(1000,5); } }你看看是这个意思么
package com.cn;import java.util.Iterator;
import java.util.Random;
import java.util.Vector;interface Observer {
public abstract void update(NumberGenerator generator);
}
abstract class NumberGenerator {
private Vector<Observer> observers = new Vector<Observer>();//存储
public void addObserver(Observer observer) {//新增
observers.add(observer);
}
public void deleteObserver(Observer observer) {//删除
observers.remove(observer);
}
public void notifyObservers() {
Iterator<Observer> it = observers.iterator();
while (it.hasNext()) {
Observer o = (Observer)it.next();
o.update(this);
}
}
public abstract int getNumber();//取得数值
public abstract void execute();//产生数值
}class RandomNumberGenerator extends NumberGenerator {
private Random random = new Random();
private int number;
public int getNumber() {
return number;
}
public void execute() {
for (int i = 0; i < 20; i++) {
number = random.nextInt(50);
notifyObservers();
}
}
}
class DigitObserver implements Observer {
public void update(NumberGenerator generator) {
System.out.println("DigitObserver:" + generator.getNumber());
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
}}
class GraphObserver implements Observer {
public void update(NumberGenerator generator) {
System.out.print("GraphObserver:");
int count = generator.getNumber();
for(int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println("");
try {
Thread.sleep(100);
} catch (Exception e) {
// TODO: handle exception
}
}
}
public class Main {
public static void main(String[] args) {
NumberGenerator generator = new RandomNumberGenerator();
Observer observer1 = new DigitObserver();
Observer observer2 = new GraphObserver();
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();
}
}
这个是不是你想要的?
因为观察者模式比较常用 ,java 就把接口给你定义好了,当然你可以自己实现。。你不觉得麻烦么? 如同 迭代器模式一样 ,java 也定义好了接口, 如同原型模式一样 ,java 也定义了 Cloneable 接口,就是这样啦,这些模式已经和java融为一体了
我是问这2种有什么区别.
你这家伙,来论坛是问问题和回答问题的,什么是没事找抽,你是故意来吵架的是吧.
我接触到的顺序是先接口回调,然后才学的观察者模式.就想问问区别.
我接触过的3个项目,都是使用回调机制的多,没有特别去使用observer和observable的.难道你一出来java就学得精通才做项目的?
当然如果你回答观察者模式的核心是回调机制,或者原理是一样的,你给我讲讲原理啊,你看你讲的什么,什么是没事找抽,真是的.闻道有先后...算了不说了
第一种方式:.继承observable类和实现observer接口 是使用了java内置的观察者模式,
注意了,observable是一个类,你必须设计一个类继承他,但是如果想某个类要继承他和其他超类的行为,那就会有困难了,毕竟java不支持多继承,还限制了obervable类的复用。 接口的方式能都很好的实现复用,所以第二种方式、;使用接口实现观察者模式比较好。
我们来看一下源码 。 observable 中有一个数据结构 private Vector obs; 用于存放 观察它的对象 ,还定义了 public void notifyObservers(Object arg) {
Object[] arrLocal; synchronized (this) {
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
} for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}
方法 ,注意这句 ((Observer)arrLocal[i]).update(this, arg); 其实这就是一个回调, 回调 observer中的update 方法。 系统实现只是将 你回调机制中的共性抽出来了,要么以后每次使用这个模式的时候都要自己重写 obserable 中的一些方法。 因为观察者模式比较常用所以和我上面说的一样,它和 迭代器 原型模式都已经固化到java 中了。 之前我说的话我道歉。。不好意思 ,我也不是故意的。。希望你能理解。
如果还有不懂的话我可以给出两个的例子。
我在把我项目的回调机制改成系统的observer的时候,发现一个问题,大概整理后原型如下:
import java.util.Observable;
import java.util.Observer;class House extends Observable {
int price;
public void setPrice(int price) {
super.setChanged();
super.notifyObservers(price);
this.price = price;
}}class HouseObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println(o);
System.out.println(arg);
}
}public class test {
public static void main(String[] args) {
House h = new House();
HouseObserver ho = new HouseObserver();
h.addObserver(ho);
h.setPrice(1000);
}
}
现在的问题是,我要在setPrice()里加多一个参数.在update()里怎么得到area的值.class House extends Observable {
int price;
public void setPrice(int price,int area) {
super.setChanged();
super.notifyObservers(price);
this.price = price;
}}class HouseObserver implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println(o);
System.out.println(arg);
//如何得到area的值
}
}public class test {
public static void main(String[] args) {
House h = new House();
HouseObserver ho = new HouseObserver();
h.addObserver(ho);
h.setPrice(1000,5);
}
}
package com.meran.normalTest;
import java.util.Observable;
import java.util.Observer; class House extends Observable {
int area;
int price;
public void setPrice(int price,int area) {
this.price = price;
this.area=area;
super.setChanged();
super.notifyObservers();
}
public int getPrice(){
return price;
};
public int getArea(){
return area;
}
} class HouseObserver implements Observer {
@Override
public void update(Observable o, Object arg) { System.out.println("price"+((House) o).getPrice());
System.out.println("area"+((House)o).getArea());
}
} public class test {
public static void main(String[] args) {
House h = new House();
HouseObserver ho = new HouseObserver();
h.addObserver(ho);
h.setPrice(1000,5);
}
}你看看是这个意思么
notifyObservers(arg); notifyObservers(); 这两个代码函数有点2。。当在被观察对象上调用 这两个方法的时候都会传递一个指向本对象的引用过去 。 也就是传一个 this
第一个相当于 (Observer).update(this,arg) 第二个(Observer).update(this,null) 这一个参数设计的莫名其妙。 要么就弄个 属性数组 全传过去 ,要么就直接没有这样让人有点小蛋疼。 其实你注意看在setPrice 我们两次调用的顺序不同
public void setPrice(int price) {
super.setChanged();
super.notifyObservers(price);
this.price = price;
}
在发出通知后我们才给对象本身参数price 赋值 如果此时在update 中调用((House)O).getPrice();输出的是 0public void setPrice(int price,int area) {
this.price = price;
this.area=area;
super.setChanged();
super.notifyObservers();}
增加参数后 我们必须先赋值了,因为我们需要通过引用来获得属性的值。
如果还和以前那样 那肯定输出 0 0
我看head.frist上 好像写这 把observable 设计为抽象类是个失败
你读一下源码就知道为什么是抽象类了, 接口只是声明实现它的子类可以提供什么服务。 抽象类中却可以定义某些共性方法的实现,当然接口也可以,通过内部类,但是我们不推荐。 你看一下observable 的实现 ,它把 addObject ,deleteObject notifyObservers();
这三个方法是 observable 的核心方法, 无论你使用什么机制实现 观察者模式,这些都是必要的,系统帮你实现好了已经, 你为什么说它不对 ? 设计成接口你还不是得自己实现? 和你自己声明有区别么???那系统还实现它干什么呢? head.first 你可以再仔细看看了。 确实 你可以说 继承了 observable 就不可以继承其他类了。但是 内部类给出了优雅的解决方案
setChanged()要放在后面...囧,虽然不知道为什么,但是还是实现了,3Q
要改过了才能通知 观察者啊。。 之前那个是因为,你直接把参数传过去了~~
后面这个是通过传过的对象来 得到属性。。 所以要现在 House 里面把 属性设置好了,然后通知已经改过了~