1.继承observable类和实现observer接口
2.不使用上面的2个,单纯使用接口回调,自己实现上面的2个方法都能实现观察者模式,有什么区别和联系吗

解决方案 »

  1.   


    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();

    }
    }
    这个是不是你想要的?
      

  2.   


    因为观察者模式比较常用 ,java 就把接口给你定义好了,当然你可以自己实现。。你不觉得麻烦么? 如同 迭代器模式一样 ,java 也定义好了接口, 如同原型模式一样 ,java 也定义了 Cloneable 接口,就是这样啦,这些模式已经和java融为一体了
      

  3.   

    不是,你的是第一种,是利用jdk自带的api.不使用这2个api,使用接口回调机制,也可以实现.
    我是问这2种有什么区别.
      

  4.   


    你这家伙,来论坛是问问题和回答问题的,什么是没事找抽,你是故意来吵架的是吧.
    我接触到的顺序是先接口回调,然后才学的观察者模式.就想问问区别.
    我接触过的3个项目,都是使用回调机制的多,没有特别去使用observer和observable的.难道你一出来java就学得精通才做项目的?
    当然如果你回答观察者模式的核心是回调机制,或者原理是一样的,你给我讲讲原理啊,你看你讲的什么,什么是没事找抽,真是的.闻道有先后...算了不说了
      

  5.   

    第二种方式实现观察者模式比较常见,
    第一种方式:.继承observable类和实现observer接口 是使用了java内置的观察者模式,
    注意了,observable是一个类,你必须设计一个类继承他,但是如果想某个类要继承他和其他超类的行为,那就会有困难了,毕竟java不支持多继承,还限制了obervable类的复用。 接口的方式能都很好的实现复用,所以第二种方式、;使用接口实现观察者模式比较好。
      

  6.   

    好吧 我错了 , 我道歉 另外 我觉得你楼上说的不大对 ,java 不支持对继承但是可以通过内部类实现多继承。
      

  7.   

    另外  你说的回调机制和实现系统接口实现是一样的。 只不过observable类和observer接口中定义了方法
    我们来看一下源码 。  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 中了。  之前我说的话我道歉。。不好意思 ,我也不是故意的。。希望你能理解。
    如果还有不懂的话我可以给出两个的例子。
      

  8.   


    我在把我项目的回调机制改成系统的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);
    }
    }
      

  9.   

    哈刚睡醒
    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);
    }
    }你看看是这个意思么
      

  10.   

    个人感觉系统实现的不给力啊。  
    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  
      

  11.   

    类和接口的区别当然 有的  如果你继承observable,那就不能继承别的类了 ,当存使用接口的话更灵活,
    我看head.frist上 好像写这 把observable 设计为抽象类是个失败
      

  12.   


    你读一下源码就知道为什么是抽象类了, 接口只是声明实现它的子类可以提供什么服务。  抽象类中却可以定义某些共性方法的实现,当然接口也可以,通过内部类,但是我们不推荐。 你看一下observable 的实现 ,它把 addObject ,deleteObject  notifyObservers();
    这三个方法是 observable 的核心方法, 无论你使用什么机制实现 观察者模式,这些都是必要的,系统帮你实现好了已经, 你为什么说它不对 ?  设计成接口你还不是得自己实现? 和你自己声明有区别么???那系统还实现它干什么呢?     head.first  你可以再仔细看看了。 确实 你可以说 继承了 observable 就不可以继承其他类了。但是 内部类给出了优雅的解决方案
      

  13.   


    setChanged()要放在后面...囧,虽然不知道为什么,但是还是实现了,3Q
      

  14.   


    要改过了才能通知 观察者啊。。 之前那个是因为,你直接把参数传过去了~~
    后面这个是通过传过的对象来 得到属性。。 所以要现在 House 里面把 属性设置好了,然后通知已经改过了~