Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java object, changed fields listener, design-pattern

There is a class:

public class MyClass {
private String field1;
private String field2;
private String field3;
// getters, setters
}

Then we update some fields

MyClass myClass = new MyClass();
myClass.setField1("field1");
myClass.setField2(null);

How can I know which fields of MyClass were tried to be changed (invoked, in the example above field1 and field2)?
What is the best solution for that? Maybe some design-pattern?
One option is to create HashSet of changed fields for this object as an additional property and update it inside each setter but it does not seem nice.
Should it be something like Proxy object which will be intercept all method calls (i.e. setXXX()) (through Java reflection?) or anything else?

UPDATE
It seems that each setter should invoke some inner method what does not seem nice as I said. And I don't need to notify any other objects about changes. I would like to store all states in this object and have access to these changes later.
In details: if method setFieldX invoked then fieldX should be marked to be updated later
P.S. All fields have different names.
Any other solutions except reflection (I want to populate object via pure setter)?

like image 996
Alex Avatar asked Jun 06 '13 06:06

Alex


2 Answers

If you want to implement using conventional design-pattern approach, I would recommend using Observer Pattern

Have a Listener for set field event of your class

public interface FieldListener {

    public void fieldValueChanged(String fieldName, Object newValue);
}

Make a class implement this listener (Observer)

public class SampleObserver implements FieldListener {

    @Override
    public void fieldValueChanged(String fieldName, Object newValue) {
        System.out.println(fieldName + " - got set with value - " + newValue);
    }

}

have a place-holder for your listeners in the Observable class (in your case MyClass) and whenever the set method gets called, just fire the event.

public class MyClass {

    List<FieldListener> listeners = new ArrayList<FieldListener>(); // the placeholder for listeners

    private String field1;
    private String field2;

    /**
     * @param field1 the field1 to set
     */
    public void setField1(String field1) {
        fireEvent("field1", field1);
        this.field1 = field1;
    }
    /**
     * @param field2 the field2 to set
     */
    public void setField2(String field2) {
        fireEvent("field2", field2);
        this.field2 = field2;
    }

    public void addListener(FieldListener l) {
        if(l != null) listeners.add(l);
    }

    public void fireEvent(String fieldName, Object newValue) {
        for(FieldListener l : listeners) {
            l.fieldValueChanged(fieldName, newValue);
        }
    }

    public static void main(String [] args) {
        MyClass m = new MyClass();
        m.addListener(new SampleObserver());
        m.setField1("s");
        m.setField2("v");
    }

}
like image 142
sanbhat Avatar answered Nov 02 '22 19:11

sanbhat


I think what you are searching the a java.bean.PropertyChangeListener which is the Observer-Pattern in Java.

Basically you add code to all setters to call the method in the PropertyChangeListener to inform all observers that the value is changed.

This is the normal Java way.

like image 5
Uwe Plonus Avatar answered Nov 02 '22 19:11

Uwe Plonus