Java против ОО Дизайн - PullRequest
       11

Java против ОО Дизайн

0 голосов
/ 22 декабря 2009

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

Это программа обработки запасов и продаж для магазина комиксов.

У меня есть класс Article, который может быть любым предметом (Магические карты, игрушки), и класс Publication, унаследованный от Article, который представляет книги и журналы. Publication имеет авторов и, при необходимости, номер выпуска, а статья - нет.

Есть редактор статей, который представляет собой графический интерфейс для создания и изменения статей. Поскольку существует возможность загрузить публикацию с ошибкой, а не добавить номер тома, интерфейс для работы со статьей:

Article a = EntityManager.loadArticle(articleId);
ArticleEditor editor = new ArticleEditor(a);
a = e.getValue();

разрешить превращение a в Публикацию, если возникнет такая необходимость.

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


Вторая проблема связана с отсутствием множественной диспетчеризации в Java (и в большинстве "корпоративных" языков): EntityManager имеет метод save(), перегруженный как для Article s, так и Publication s. Это вызывает огромную проблему, если я скажу, например:

Article a = EntityManager.loadArticle(articleId);
ArticleEditor editor = new ArticleEditor(a);
a = e.getValue();
EntityManager.save(a);

В настоящее время это "решается", когда ArticleEditor сохраняет изменения (что кажется неправильным).

Я уверен, что должен быть какой-то способ изменить дизайн, чтобы устранить эти проблемы. (Я не против переписать, если это будет необходимо.)

Как настроить дизайн для устранения этих проблем?

Редактировать: в публикации есть и авторы, не только числа.

Ответы [ 6 ]

2 голосов
/ 22 декабря 2009

Я не знаю, насколько радикально вы хотите провести рефакторинг этой системы, но я подозреваю, почему у вас будет отдельный класс Publication только потому, что это статья, в которой есть номер публикации. Особенно, когда вы упоминаете о необходимости изменить статью на публикацию в некоторых случаях. Вы можете разрешить Статье иметь свойство "номер публикации", которое может быть нулевым, если статья не является публикацией. Это устраняет необходимость превращения Статьи в Публикацию (просто установите для свойства ненулевое значение) и устраняет вашу проблему с EntityManager.

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

1 голос
/ 23 декабря 2009

Полагаю, вы имели в виду a = editor.getValue(); в своих примерах?

Проблема 1 на самом деле не является проблемой, если вы не говорите, что ваша Статья и Публикация являются неизменяемыми классами? Редактор создается на экземпляре Article, и если он работает со ссылкой на этот объект, его содержимое изменится (возможно, изменит его после отмены подтверждения / отката в пользовательском интерфейсе.)

Из вашего описания я предполагаю, что Article действует как «шаблон» для Publication, и что в вашем пользовательском интерфейсе действие создать публикацию отделено от edit Article или Publication. Вы можете написать код создания новой публикации следующим образом:

Publication p = EntityManager.newPublication(articleId);
ArticleEditor editor = new ArticleEditor(p);

Проблема 2 может быть решена путем реализации метода сохранения в статье и перегрузки его в публикации:

interface ArticleStore {
}

class Article {
    void save(ArticleStore store);
}

class EntityManager implements ArticleStore {
     void save(Article a) {
         a.save(this);
     }
}

Методы save в Article и Publication могут вызывать методы в интерфейсе ArticleStore, это не потребует изменений в EntityManager, если в иерархию добавлен новый подкласс.

Редактировать Обновлено, чтобы отразить комментарий.

0 голосов
/ 23 декабря 2009

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

+-------------+             +---------+
| Publication |--- has-a ---| Article |
+-------------+             +---------+

Таким образом, класс Publication будет иметь поле типа Article articleReference и все поля, необходимые для моделирования публикации. Сохранение статьи не будет мешать публикациям, сохранение публикации сохранит публикацию и связанную статью.

Редактор публикаций может расширить редактор статей и добавить необходимые поля графического интерфейса публикации.

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

Редактировать

Я предлагаю вам переименовать класс 'Article', потому что его можно принять за написанную статью как часть публикации. В моем примере «Article» используется точно так же, как описано в вопросе , в качестве некоторой модели основных данных для всех видов элементов, включая публикации.

0 голосов
/ 23 декабря 2009

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

0 голосов
/ 22 декабря 2009

У меня нет первого вопроса. Что касается второго, это правда, что иногда требуется многократная отправка, но, вероятно, не в вашем случае, просто if(article instanceof Publication) save((Publication)article) просто отлично. У вас есть только несколько классов, не пытайтесь переоценить их.

0 голосов
/ 22 декабря 2009
  1. В чем проблема? Мне кажется, это нормально.
  2. Не можете ли вы смоделировать множественную диспетчеризацию в Java с помощью отражения?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...