如何在自定义对象扩展后立即观察它

时间:2011-10-10 07:13:24

标签: java inheritance field onchange listeners

所以假设我在java中有一个自定义对象:

   public class TestObject {

    private int value = 0;

        public TestObject(int value) {
                this.value = value;
        }

    public void increaseValue() {
        value++;
    }

    }

现在我想知道何时修改此对象。或者更具体地说,我想知道它的任何字段何时发生了变化(在这种情况下是值)。此外,如果我扩展TestObject,我仍然希望能够监听可能发生在该对象上的任何字段更改,包括该更改是否为新字段的新字段。

我已经做了一些研究,发现了java附带的各种听众,但他们似乎都失败了,他们要求你在方法结束时向听众发出呼叫。例如,increaseValue()还必须通知TestObject的所有侦听器,该值已更改。显然这对我不起作用,因为可扩展性是必须的,我不知道如果从该对象继承的人将遵守他们必须通知听众的要求。更不用说,为每个mutator方法编程都似乎很痛苦

如果能够解决这个问题,我们将不胜感激。

3 个答案:

答案 0 :(得分:1)

您可以使用approach that Hibernate uses,即仪器/代理您的类,在POJO的getter和setter周围添加额外的(监听器)逻辑。但是,您需要确保所有只使用代理类。

答案 1 :(得分:1)

  

更不用说,为每个人编程都似乎很痛苦   变异方法

看看The AspectJ Project。使用pointcut for field assignment

,您可以使用生产方面轻松实现此目的
public privileged aspect TestObjectObserver {
    before(Object o) : set(* TestObject.*) && args(o) {
      // notify listeners
    }
} 

// runs before field assignment to any field of TestObject. The value to be
// assigned is converted to an object type (int to Integer, for
// example) and named o in the body

// the aspect needs to be declared privileged so access private fields

答案 2 :(得分:1)

  

显然这对我不起作用,因为可扩展性是必须的   我和我不知道如果那些人继承了那个对象   将遵守他们必须通知听众的要求

您的方法不正确。

您不能强制派生类来保持基类的不变量,因为继承可以允许后代类以从父类的角度看它们无效的方式更改实现。

在您的情况下,派生类可能或可能不会在修改时调用通知。

在这种情况下,您应该对Composition而不是Inheritence进行建模 Composition vs Inheritence

对于你的例子:

class Value{    
    private int value;   
     public void increaseValue() {  
            value++;  
     }  
}

值知道如何增加自己。

class ValueHolder extends Observable {  
       private Value theValue;  
       public ValueHolder(Value v){  
          theValue = v;  
       }
       public void modifyValue(String methodName)(){  
           Method method = theValue.getClass().getMethod(methodName, null);  
           method.invoke(theValue,null);//Since it has no args           
           setChanged();  
           notifyObservers();  
       }  
    }

所以所有代码如下:

ValueHolder vh = new ValueHolder(new Value(10));  
//registration of listeners
vh.modifyValue("increaseValue");  

//So if you extend the Value 
class DerivedValue extends Value{    
    private int y;   
     public void increaseY() {  
            y++;  
     }  
}  

ValueHolder vh = new ValueHolder(new DerivedValue());  
//registration of listeners
vh.modifyValue("increaseY);    

所以现在的问题是对象的使用是通过持有者 然后会发生通知。