Типизированного свойства Java с событий и отражения среды выполнения


Цель: типизированного события PropertyChanged, как, минимум усилий для события PropertyChanged, отражения среды выполнения свойств.

Я изобретать колесо или я создал что-то стоящее? Вы бы использовать его в вашем следующем проекте?

public interface StaticProperty {
  public boolean canGet();                     /** assert canGet()] */
  public boolean canSet();
  public boolean isvalid();                    /** return rules().areAllMet() */
  public boolean supportsPersistence();        /** assert instanceof Serializable && new T() */
  public boolean canReturnNull();              /** assert canReturnNull && this.property != null */
  public boolean canSetToNull();               /** assert canSetToNull() && value != null */
  public boolean firesEvent();

  public abstract class AbstractProperty
    implements
      StaticProperty {

    protected boolean canGet = false;          /** All false by default: explicitly set true in base */
    protected boolean canGetNull = false;
    protected boolean canSet = false;
    protected boolean canSetNull = false;
    protected boolean isValid = false;
    protected boolean firesEvent = false;
    protected boolean supportsPersistence;

    protected AbstractProperty() {}
    @Override public boolean canSet() {
      return canSet;
    }
    @Override public boolean canSetToNull() {
      return canSetNull;
    }
    @Override public boolean canReturnNull() {
      return canGetNull;
    }
    @Override public boolean firesEvent() {
      return firesEvent;
    }
    @Override public boolean isvalid() {
      return isValid;
    }
    @Override public boolean canGet() {
      return canGet;
    }
    @Override public boolean supportsPersistence() {
      return supportsPersistence;
    }
  }
}

public class Props {
  /**
   * Any class having either getters, setters, or both
   * With this, you can do:
   *  
   *  for (Property property : someObject.properties()) {
   *    query.select(property.name())
   *         .from(someObject.name());
   *  }
   *    
   * */
  public interface HasProperties {
    public PropertyTypeList properties();
  }

  public interface IsChild<H extends HasSetters> {
    public void doSet(H hasProperty);            /** Dispatch setting to the property itself */
  }

  /**
   * A readonly property  
   * */
  public interface HasGetters extends HasProperties {
    public IsChild getProp(StaticProperty type);
  }

  public interface FakeProperty extends HasGetters {

  }

  /** Write only property */
  public interface HasSetters extends HasProperties {
    public void setProp(StaticProperty type, IsChild value);
  }

  /** Because each property needs a dispatch method set(HasProperty parent), simple value types
   * must be wrapped. */
  public interface Value {
    public interface StringValue extends Value {
      public String value();
    }

    public interface IntValue extends Value {
      public int value();
    }

    public interface DoubleValue extends Value {
      public double value();
    }

    public interface DateValue extends Value {
      public java.util.Date value();
    }

    public interface MultiValue extends Value {
      public interface ValueList extends ImmutableList<Value> {}

      public ValueList value();
    }
  }

  public interface Handler<P extends IsChild> {
    public void changed(P newProp, P oldProp);

    public interface Handle {
      public void remove();
    }
  }

  public interface NotifiesPropertyChange {
    // Type-safe property handling
    public void addHandler(StaticProperty type, Handler handler);

    // Register handling of any property change
    public void addHandler(Handler handler);
  }

  /** Keeps track of property values, fires events, dispatches to property */
  public static interface PropertyList
    extends
      ImmutableList<StaticProperty> {

    public <H extends HasSetters, P extends IsChild> void set(StaticProperty type, P value, H hasProp);
    public IsChild get(StaticProperty type);
    public <H extends HasSetters, P extends IsChild> void setWithoutDispatch(StaticProperty type, P value, H hasProp);
    public PropertyTypeList types();
    public void addHandler(StaticProperty type, Handler handler);
    public void addHandler(Handler handler);

    public static class PropertyTypeList
      extends
        ImmutableListImpl<StaticProperty> {

      public PropertyTypeList(List<StaticProperty> properties) {
        super(properties);
      }
      public PropertyTypeList(StaticProperty... properties) {
        super(properties);
      }
      @Override public String toString() {
        return "PropertyTypeList [items=" + items + "]";
      }
    }

    public static class Impl
      extends
        AbstractImmutableList<StaticProperty>
      implements
        PropertyList {

      private final static boolean doDispatch = true;
      private final static boolean ignoreDispatch = false;

      private List<StaticProperty> types = new ArrayList<StaticProperty>();
      private Map<StaticProperty, IsChild> properties = new HashMap<StaticProperty, IsChild>();
      private Map<Class, List<Handler>> handlers = new HashMap<Class, List<Handler>>();
      private List<Handler> geenricHandlers = new ArrayList<Handler>();

      /** Construct from a list of property types */
      public Impl(PropertyTypeList items2) {
        for (StaticProperty p : items2) {
          properties.put(p, null);
          types.add(p);
        }
      }
      /** Returns all the registered property types */
      public PropertyTypeList types() {
        return new PropertyTypeList(types);
      }
      @Override protected List<StaticProperty> createList() {
        return new ArrayList<StaticProperty>();
      }
      /** Asserts given property is present and returns it */
      public IsChild get(StaticProperty type) {
        assert properties.containsKey(type);
        return properties.get(type);
      }
      /** Asserts given type is present and sets the property, dispatching to the property */
      @Override public <H extends HasSetters, P extends IsChild>
          void set(StaticProperty type, P value, H hasProp) {
        assert properties.containsKey(type.getClass());
        doSet(type, value, hasProp, doDispatch);
      }
      /** Sets target property _without_ dispatching to the property */
      @Override public <H extends HasSetters, P extends IsChild>
          void setWithoutDispatch(StaticProperty type, P value, H hasProp) {
        doSet(type, value, hasProp, ignoreDispatch);
      }
      /** Sets the new value, dispatches to property and fires event */
      private <H extends HasSetters, P extends IsChild<H>>
          void doSet(StaticProperty type, P value, H hasProp, boolean setParent) {
        assert value != null && type.canSetToNull();
        properties.put(type, value);
        if (setParent)
          value.doSet(hasProp);
        if (type.firesEvent())
          onChanged(type, value, null);
      }
      /** Adds handler for target property */
      @Override public void addHandler(StaticProperty type, Handler handler) {
        if (!handlers.containsKey(type.getClass()))
          handlers.put(type.getClass(), new ArrayList<Handler>());
        handlers.get(type.getClass()).add(handler);
      }
      /** Adds handler for any property change event */
      public void addHandler(Handler handler) {
        geenricHandlers.add(handler);
      }
      /** Fires event for target property and generic event */
      public <P extends IsChild> void onChanged(StaticProperty type, P p, P old) {
        List<Handler> handlersForType =  handlers.get(type.getClass());
        if (handlersForType != null)
          for (Handler handler : handlersForType)
            handler.changed(p, old);
        for (Handler hanlder : geenricHandlers)
          hanlder.changed(p, old);
      }
    }

  }


}




  public interface Woei
          extends
          HasName, SetsName,
          HasDescription, SetsDescription,
          NotifiesPropertyChange {

    public static WoeiName nameP = new WoeiName();
    public static WoeiDescription descriptionP = new WoeiDescription();

    /** Extend properties and set rule values after calling the super constructor */
    public static class WoeiName extends AbstractProperty {
      public WoeiName() {
        canSetNull = false;
        firesEvent = true;
        isValid = true;
        canGetNull = true;
      }
    }

    public static class WoeiDescription extends AbstractProperty {
      public WoeiDescription() {
        canSetNull = false;
        firesEvent = true;
        isValid = true;
        canGetNull = true;
      }
    }

    public static class WoeiImpl
            implements Woei {
      private static PropertyTypeList propertyTypes = new PropertyTypeList(nameP, descriptionP);
      private PropertyList properties = new PropertyList.Impl(propertyTypes);
      private Name name;
      private Description description;

      @Override public IsChild getProp(StaticProperty type) {
        return properties.get(type);
      }
      @Override public PropertyTypeList properties() {
        return properties.types();
      }
      @Override public Name name() {
        return name;
      }
      @Override public void setName(Name name) {
        this.name = name;
        properties.setWithoutDispatch(nameP, name, this);
      }
      @Override public void setProp(StaticProperty type, IsChild value) {
        properties.set(type, value, this);
      }
      @Override public Description description() {
        return description;
      }
      @Override public void setDescription(Description description) {
        this.description = description;
        properties.setWithoutDispatch(descriptionP, description, this);
      }
      @Override public void addHandler(StaticProperty type, Handler handler) {
        properties.addHandler(type, handler);
      }
      @Override public void addHandler(Handler handler) {
        properties.addHandler(handler);
      }
    }
  }


612
4
задан 19 октября 2011 в 07:10 Источник Поделиться
Комментарии
1 ответ

Я искренне считаю, что ваш код страдает от более-инженерии.

Как вы можете видеть в своей мощной дистрибьюторской сети, интерфейс и WoeiImpl класса, есть много кода, который требуется использовать то, что вы строите здесь. Чтобы быть тупым, я ответить бы вам использовать его в вашем следующем проекте? с НЕТ.


Относительно этого кода:

for (Property property : someObject.properties()) {
query.select(property.name())
.from(someObject.name());
}

Если вы хотите создать SQL-запрос для поиска свойств, таких как ты здесь делаешь, я рекомендую использовать режим гибернации (что упрощает это много, когда вы на самом деле сделать всю систему и работает правильно...)


Если я хочу, чтобы выполнить событие, когда свойство изменилось, я переопределить соответствующий набор-метод в мой код, чтобы делать то, что я хочу быть сделано всякий раз, когда свойство изменяется.

Есть слишком много интерфейсов, которые должны быть реализованы/расширенная для меня, хотят использовать ваш код. Я не думаю, что это стоит всех неприятностей, ваш код просто, чтобы сделать его немного более безопасным, я бы предпочел использовать встроенный отражения Java API-интерфейс.

5
ответ дан 26 ноября 2013 в 01:11 Источник Поделиться