Добавление функциональности: подкласс против декоратора - PullRequest
0 голосов
/ 26 августа 2009

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

На данном этапе приложение «работает», вроде. Текущая реализация, обрабатывающая механизм правил и обновления интерфейса, не очень элегантна и состоит из большого набора операторов if, подобных:

if(screenObj instanceof CoreInputText) {
    ((CoreInputText) screenObj).setDisabled(true);
}

Чтобы усложнить микширование, у нас также есть свои собственные объекты, смешанные таким образом, что набор в целом не имеет общего предка, что исключает нашу возможность сделать что-то вроде:

((CommonAncestor) screenObj).setDisabled(true);

Вопрос в том, стоит ли переделывать эту часть кода, чтобы она была чище и понятнее. Поскольку большинство элементов экрана являются элементами ADF Faces, мы не можем / не можем изменить их происхождение, чтобы добавить дополнительные методы.

Цель изменения кода будет двоякой: очистить старый код и улучшить базу кода, чтобы добавление новых элементов или элементов управления не приводило к значительному изменению кода (особенно к операторам if, которые существуют в многочисленные места).

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

Любой вклад в методы для обработки таких ситуаций, кроме подклассов и декораторов, приветствуется!

1 Ответ

1 голос
/ 26 августа 2009

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

Кроме того, если это настоящий установщик, вы можете использовать BeanUtils из apache и просто установить его как свойство с именем disabled.

РЕДАКТИРОВАТЬ: Учитывая, что они не имеют того же метода, некоторый код придется добавлять каждый раз, когда вы добавляете новый объект, если только вы не можете хотя бы контролировать, что у новых объектов в будущем будет определенный интерфейс. При этом, если вам удобно идти по пути отражения, вы можете создать карту классов для методов (при условии, что все методы принимают логическое значение - и вы можете даже обойти это, если нужно) и найти объект на карте. Таким образом, когда вы вводите новый объект, вам нужно только добавить запись на карту.

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

...