Сгенерировать метод, возвращающий список неизменяемых EMF

Я использую EMF через аннотированный код Java следующим образом

/**
 * Adds the given type to this filter. Has no effect if the given type
 * already belongs to this filter.
 * 
 * @param type
 *            the type to add
 * @model
 */
public void addEntityType(String type);

/**
 * Returns the list of types belonging to this filter. Types are identified
 * by there name.
 * 
 * @return the list of types for this entity type filter
 * 
 * @model
 */
public List<String> getEntityTypes();

/**
 * Removes the given type from this filter. Has no effect if the given type
 * doesn't belong to this filter.
 * 
 * @param type
 *            the type to remove
 * @model
 */
public void removeEntityType(String type);

После создания файлов ecore и genmodel из этого аннотированного интерфейса и после генерации кода метод getEntityTypes изменяется следующим образом:

public EList<String> getEntityTypes();

В целях инкапсуляции я хочу, чтобы этот EList был немодифицируемым, поэтому код клиента интерфейса может изменять список только с помощью методов добавления и удаления.

Есть ли какой-либо чистый способ сделать это, например, изменить аннотацию Java или файл genmodel, чтобы сообщить генератору о создании кода, возвращающего неизменяемый список? (Я не смог найти это после поиска в гугле...)

Как вы справляетесь с такими ситуациями?

заранее спасибо

Ману


person Manuel Selva    schedule 12.06.2009    source источник


Ответы (1)


Вам нужно будет изменить сгенерированный класс «Impl», чтобы он выглядел следующим образом:

/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated
 */
private EList<String> getEntityTypesGen() {
    if (entityTypes == null) {
        entityTypes = new EDataTypeUniqueEList<String>(String.class, 
            this, NsPackage.THINGY__ENTITY_TYPES);
    }
    return entityTypes;
}

public EList<String> getEntityTypes() {
    return ECollections.unmodifiableEList(getEntityTypesGen());
}

/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated NOT
 */
public void addEntityType(String type) {
    getEntityTypesGen().add(type);
}

/**
 * <!-- begin-user-doc -->
 * <!-- end-user-doc -->
 * @generated NOT
 */
public void removeEntityType(String type) {
    getEntityTypesGen().remove(type);
}

Обратите внимание, что я сделал следующее:

  1. Изменено имя и видимость сгенерированного метода getEntityTypes на getEntityTypesGen и private соответственно. EMF не будет мешать видимости, когда он регенерирует этот метод. Кроме того, EMF продолжит генерировать этот метод с суффиксом «Gen», даже несмотря на то, что теперь у нас есть несгенерированный метод getEntityTypes.
  2. Добавлен общедоступный несгенерированный метод getEntityTypes, который упаковывает результат реализации по умолчанию в неизменяемый список EList.
  3. Реализованы (и изменены на несгенерированные) методы add/removeEntityType путем делегирования сгенерированному методу getEntityTypesGen (результат которого по-прежнему можно изменить).

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

person Mark    schedule 13.06.2009