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

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

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

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

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

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

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

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

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

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

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

Быстрый способ решить эту проблему дизайна - создать интерфейс под названием «ObjectWithMethods», который будут реализовывать мои классы Class и Interface. Таким образом, мне нужно будет только добавить параметр ObjectWithMethods в мой класс AttributesPanel.

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

Что вы думаете?

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

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

Гийом.

В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
2
0
502
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

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

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

Конечно, моего описания недостаточно для реализации этой техники, поэтому вы захотите прочитать о ней. Я думаю, это хорошо задокументировано. Например, я нашел это примерно за 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

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

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