элегантная иерархия объектов - PullRequest
3 голосов
/ 23 ноября 2010

во-первых, простите мой псевдокод, я думаю, что в этом случае он более разборчив, чем полный код.Пожалуйста, предположим, что свойство в псевдокоде на самом деле является полем с методом getter & setter, за исключением ArticleElement, где ему просто необходимо свойство, доступное из объекта с помощью метода прямого получения или двухэтапногоМетод получения (т. е. getArticleSource().getName()).

Скажем, у меня есть объект шаблона:

ArticleTemplate
    Long id;
    String name;
    String description;
    Integer amount;
    Schedule schedule;

, и он используется (по расписанию) для создания множества потенциальных дочерних объектов на разные даты:

Article
    Long id;
    String name;
    String description;
    Integer amount;
    Date date;
    Boolean complete;
    ArticleTemplate template;

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

для моего пользовательского интерфейса Я хочу создать отсортированный и объединенный списокиз:
a) потенциальных дочерних сущностей из родительских сущностей
b) реальных дочерних сущностей, ранее созданных из родительских сущностей
c) сиротских дочерних сущностей, созданных автономно

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

ArticleElement
    // actual value if from Article, null if from potential from ArticleTemplate
    Long id;
    // actual value if from Article or ArticleTemplate
    String name;
    // actual value if from Article or ArticleTemplate
    String description;
    // actual value if from Article or ArticleTemplate
    Integer amount;
    // actual value if from Article, simulated if from potential from ArticleTemplate
    Date date;
    // actual value if from Article, false if from potential from ArticleTemplate
    Boolean complete;
    // actual value (nullable) if from Article, self if from potential from ArticleTemplate
    ArticleTemplate template;
    // false if from Article, true if from potential from ArticleTemplate
    Boolean templateSimulation;
    // once the list is sorted, a running tally of this.amount is to be stored on this object
    Integer runningTally;
    // would be type of interface if Article and ArticleTemplate implement same
    Object source;

Ясно, что у меня будет как минимум 3 класса, но есть несколькоразличные подходы с интерфейсами и т. д.

Я бы хотел избежать клонирования и копирования свойств везде, где это возможно, и использовать наследование там, где это выгодно.

предложения приветствуются!

стр.

1 Ответ

0 голосов
/ 24 ноября 2010

Вот мое текущее решение, и я не уверен, что оно мне нравится, но я пока что не нашел ничего лучшего:

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

создание контракта пользовательского интерфейса

public interface UiElement<T>
{
    T getSource();
    Class<T> getType();
    // redundant - refer to source
    // Long getId();
    String getName();
    String getDescription();
    Integer getAmount();
    Date getDate();
    Boolean getComplete();
    // redundant - not needed anymore
    // ArticleTemplate getTemplate();
    // redundant - replaced by getType()
    // Boolean getTemplateSimulation(); 
    Integer getRunningTally();
}

создание реализации для Article - пропуск через контрактные вызовык исходному объекту для большинства свойств

public class ArticleUiElement implements UiElement<Article>
{
    private Article source;
    private Integer tally;

    public ArticleUiElement(Article source) {
        this.source = source;
    }

    public Article getSource() {
        return source;
    }

    public Class<Article> getType() {
        return Article.class;
    }

    public String getName() {
        return source.getName();
    }

    public String getDescription() {
        return source.getDescription();
    }

    public Integer getAmount() {
        return source.getAmount();
    }

    public Date getDate() {
        return source.getDate();
    }

    public Boolean getComplete() {
        return source.getComplete();
    }

    public String getRunningTally() {
        return tally;
    }

    public void setRunningTally(String tally) {
        this.tally = tally;
    }
}

создайте реализацию для ArticleTemplate - передайте контрактные вызовы к исходному объекту для большинства свойств

public class ArticleTemplateUiElement implements UiElement<ArticleTemplate>
{
    private ArticleTemplate source;
    private Integer tally;
    private Date date;

    public ArticleTemplateUiElement(ArticleTemplate source) {
        this.source = source;
    }

    public ArticleTemplate getSource() {
        return source;
    }

    public Class<ArticleTemplate> getType() {
        return ArticleTemplate.class;
    }

    public String getName() {
        return source.getName();
    }

    public String getDescription() {
        return source.getDescription();
    }

    public Integer getAmount() {
        return source.getAmount();
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Boolean getComplete() {
        return false;
    }

    public String getRunningTally() {
        return tally;
    }

    public void setRunningTally(String tally) {
        this.tally = tally;
    }
}

может кто-то предложить улучшения или совсем лучшерешение?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...