Плохая проблема с дизайном OO - мне нужна некоторая общая функциональность в Java, но я не знаю, как ее реализовать

StackOverflow https://stackoverflow.com/questions/125463

  •  02-07-2019
  •  | 
  •  

Вопрос

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

Проект довольно продвинутый :Я могу создавать классы, перемещать их, создавать интерфейсы, создавать ссылки и т.д.

Над чем я работаю, так это над диалоговым окном для настройки свойств класса / интерфейса и создания новых классов / интерфейсов.

Например, у меня есть класс, который расширяет JDialog.Это главное "окно" для редактирования классов и интерфейсов (ну, там для каждого свой класс).Он содержит JTabbedPane, которые, в свою очередь, содержат JPanels.

Эта JPanel на самом деле является пользовательской.Я создал абстрактный класс, который расширяет JPanel.Этот класс использует компоненты (определенные его подклассами) и добавляет их значения в JTable (также содержащуюся в JPanel).

Например, если я хочу отредактировать атрибуты класса, JPanel будет содержать JTextField для ввода имени атрибута, а также другое поле для ввода его типа.Существует также набор кнопок для обработки данных, введенных в эти поля.Когда я нажимаю "Сохранить", данные, которые я ввел в JTextFields, добавляются в JTable (а-ля Enterprise Architect).Конкретный класс, который расширяет абстрактный, отвечает за определение элемента управления и принятие решения о том, что делать с данными при добавлении или удалении строки из JTable.Однако ответственность за управление JTable лежит на абстрактном классе.

Вот в чем моя проблема :в OO у класса есть методы, и у интерфейса тоже есть методы.Я сказал себе :Я мог бы использовать ту же конкретную пользовательскую JPanel (AttributesPanel (которая расширяет созданный мной абстрактный класс JPanel)) для хранения методов для класса или интерфейса and.

Однако классу необходимо сохранить копию (в качестве атрибута) класса или интерфейса, над которым я работаю.Таким образом, когда к нему добавляется метод, я могу вызвать editedClass.addMethod() (или editedInterface.addMethod()) .Проблема в том, что у меня нет способа определить, работаю ли я с классом или с интерфейсом and.

Решение, которое я нашел, уродливое :сохраните атрибут editedClass и атрибут editedInterface в классе AttributesPanel.В зависимости от того, редактирую ли я класс или интерфейс, один из этих атрибутов будет равен null, в то время как для других - нет.

По-моему, это довольно некрасиво.На самом деле, я могу слышать, как мои учителя программной инженерии в моей голове кричат в агонии, сгорая (ну, на самом деле, замерзая) в девятом круге Ада.

Быстрым способом исправить эту проблему проектирования было бы создать интерфейс под названием "ObjectWithMethods", который будут реализовывать мой класс и интерфейсные классы.Таким образом, мне нужно будет только поместить параметр ObjectWithMethods в мой класс AttributesPanel.

Но означает ли это, что я должен создать класс с именем "ObjectWithAttributes" или "ObjectWithBlahBlah"?Я вижу здесь хороший потенциал "TheDailyWTF"...Кроме того, я не думаю, что мне следует изменять объекты моего домена (класс, Интерфейс, Примечание, Отношение (для моего редактора UML)) или создавать новый интерфейс только ради какого-то рассмотрения пользовательского интерфейса....

А ты как думаешь?

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

Ваше здоровье,

Гийом.

Это было полезно?

Решение

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

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

Конечно, моего описания недостаточно для реализации этой техники, поэтому вы захотите ознакомиться с ней подробнее.Я думаю, что это хорошо задокументировано.Например, я нашел это примерно за 2 секунды в java, что должно помочь вам начать: http://www.javaworld.com/javaworld/javatips/jw-javatip98.html

Другие советы

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

В вашем конкретном случае я бы рассмотрел возможность реализации диаграмм, представленных в Спецификация UML, потому что они были так любезны указать UML, используя UML-нотацию!

У вас есть заявка.В этом приложении.вы представляете и редактируете некоторые данные.

Эти данные представляют класс языка программирования или интерфейс языка программирования.

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

То же самое относится к полю или свойству, которое указывает, редактируете ли вы класс или интерфейс.

Я предлагаю кое-что сделать.

Отделите представленные данные от кода или логики вашей программы:

если у вас есть что-то вроде:

// all code, classes, mixed up
public class JCustomPanel:  {

    protected ChartClass Charts;
    protected ArrayList<String> MyClassAttributes;
    protected ArrayList<String> MyClassMethods;

    void PanelDoSomeThing();
    void ClassDoSomeThing();
    void InterfaceDoSomeThing();

    // ...
} // class JCustomPanel

Перейдите к этому:

// things related to a single class or interface,
// nothing to do with the chart

public class JClassRepresentation:  {

    ArrayList<String> Attributes;
    ArrayList<String> Methods;

    bool IsInterface;

    void ClassDoSomeThing();
    void InterfaceDoSomeThing();

    // ...
} // class JCustomPanel

// things related to the editor,
// contains the classes and interfaces,
// but, as separate stuff
public class JCustomPanel:  {

    ArrayList<JClassRepresentation> Classes;

    int PagesCount;

    void InterfaceDoSomeThing();

    // ...
} // class JCustomPanel

Ваше здоровье.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top