We were applying MVP-like style and then faced with the question: How a Presenter should tell a View to change its state?
Brute force approach looks like following:
public class Presenter { private View view; public void doSomething() { //Here, services are processing something really important view.setTitle( "Updated" ); view.setName( "New name" ); } } public class Form extends JFrame implements View { private JTextfield nameTf; @Override public void setTitle( String title ) { setTitle( title ); } @Override public void setName( String name ) { nameTf.setText( name ); } }Well, this is actually ok, but the more components you have on the form, more verbose View interface becomes.
The move I am talking above is encapsulating a setter into separate object. Look here:
public abstract class ValueSetter { private static Map<Class<?>, ValueSetter> SETTERS; static { SETTERS = new HashMap<Class<?>, ValueSetter>(); SETTERS.put(JTextField.class, new JTextFieldSetter()); } public static ValueSetter get( Class<?> type ) { if( SETTERS.containsKey(type) ) { return SETTERS.get(type); } throw new IllegalArgumentException( "Missing ValueSetter for " + type ); } public abstract void set( Object target, Object value ); private static class JTextFieldSetter extends ValueSetter { @Override public void set(Object target, Object value) { ((JTextField)target).setText( (String) value ); } } private static class JFrameSetter extends ValueSetter { @Override public void set(Object target, Object value) { ((JFrame)target).setTitle( (String) value ); } } }Now it is possible to write more elegant code:
public class Form extends JForm implements View { private Map<String, JComponent> components; @Override public void updateComponent(String id, Object value) { JComponent component = components.get(id); ValueSetter.get(component.getClass()).set(component, value); } }So thanks Marcin for this nice tip and fresh idea for me ;)
No comments:
Post a Comment