Могу ли я создать экземпляр подкласса, зная некоторое значение свойства этого подкласса - PullRequest
0 голосов
/ 30 сентября 2011

У меня есть иерархия так называемых классов атрибутов, которая представляет отдельные свойства моей доменной модели. Каждый из этих классов атрибутов имеет уникальное свойство идентификатора String. У меня также есть AttributeFactory, у которого есть метод для получения экземпляров Attribute на основе идентификатора.

public class Attribute {
    private String id;
    private AttributeType type;
    .......
    .......

    public Attribute(String id){
       this.id=id;
    }

    public void setID(String id){
       this.id=id;
    }

    public String getID(){
       return this.id; 
    }

    .......
    .......
}

Интерфейс фабрики выглядит как

public interface IAttributeFactory {

    Attribute getAttributeByID(String id);
}

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

Пример подкласса атрибута:

public class ClientCode extends Attribute {

    public ClientCode(){
        super("clientCode");
        this.setType(AttributeType.CHAR_TYPE);
    }

    ........
    ........
}

Вопрос в том, можем ли мы с помощью отражения или любого другого объекта создавать новые экземпляры подклассов атрибутов, только зная идентификатор этих подклассов, поэтому реализуем интерфейс, определенный выше, без необходимости определять HashMap и добавлять каждый новый определенный подкласс к HashMap?

Заранее спасибо Daniel

Ответы [ 2 ]

1 голос
/ 30 сентября 2011

Если идентификаторы произвольно выбраны клиентским кодом, тогда невозможно будет узнать, какой идентификатор принадлежит какому подклассу атрибута. Однако, если вы можете каким-то образом применять шаблон, то да, было бы возможно создать экземпляры подклассов, только зная идентификатор. Вы можете сделать это с помощью отражения.

Пример кода ниже, как создать новый экземпляр с помощью отражения:

public void createInstanceOfSubclass(String id) {
     try {
       Class cls = Class.forName(convertIDToClassName(id));
       Class parameterTypes[] = new Class[1];
       parameterTypes[0] = String.TYPE;
       Constructor ct = cls.getConstructor(parameterTypes);

       Object arglist[] = new Object[1];
       arglist[0] = id;
       Object subclassInstance = ct.newInstance(arglist);
     }
     catch (Throwable e) {
        System.err.println(e);
     }
}

[Это просто пример кода; например, обработка ошибок может быть улучшена в реальной реализации.]

По сути, вам придется написать метод convertIDToClassName (String) для преобразования идентификатора в имя класса. Без такой ассоциации было бы невозможно связать их.

Другая идея заключается в том, что идентификатор атрибута рассчитывается вами; Это означает, что класс Attribute устанавливает свое собственное поле ID. В результате вы напрямую связываете имя подкласса и поле ID вместе. Следовательно, было бы возможно создавать экземпляры подклассов через идентификатор.

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

0 голосов
/ 01 октября 2011

Вам нужна фабрика для создания экземпляра определенного подкласса Attribute, верно? Давайте сделаем это, используя типичный заводской шаблон.

//TODO make this a singleton
public final class ClientFactory implements IAttributeFactory {

  public static final String CLIENT_CODE = "clientCode"; //TODO use enum 

  /** This can return a null */
  public final Attribute getAttributeByID(String id) { //TODO rename this getter to something like create
    if (null == id) return null;
    if(id == CLIENT+CODE)
      return new ClientCode(CLIENT_CODE);
    return null;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...