Встраиваемый объект (Pluggable Object)
Как можно выразить несколько разных вариантов повед ения код а?
Проще всего использовать явный условный оператор:
if(circle) then {
… код , отно сящийся к circle.
} else {
… код , не отно сящийся к circle
}
Од нако под обный корявый код имеет тенд енцию распро страняться
по всей программе. Если д ля опред еления разницы межд у окружно стями
и не окружно стями вы буд ете использовать условный оператор хотя бы
в од ном месте вашего код а, с большой д олей уверенно сти можно
сказать, что позд нее под обный оператор прид ется д обавить также в
д ругом месте, затем в третьем и т. д .
Вторая по важно сти зад ача TDD – устранение д ублирования,
поэтому вы д олжны под авить угрозу распро странения явных условных
операторов в зарод ыше. Если вы вид ите, что од но и то же условие
проверяется в д вух разных местах вашего код а, значит, настало время
выполнить
базовое
объектно-ориентированное
преобразование:
«Встраиваемый объект» (PluggableObject).
Иногд а обнаружить необход имо сть применения этого шаблона не
так про сто. Од ин из самых любимых мною примеров использования
встраиваемого объекта был прид уман мною и Эрихом Гаммой.
Пред ставьте, что мы занимаемся разработкой графического ред актора.
Если вы когд а-нибуд ь занимались чем-либо под обным, д олжно быть, вы
знаете, что операция выд еления объектов облад ает несколько
усложненной логикой. Если указатель мыши наход ится над графической
фигурой и пользователь нажимает кнопку мыши, значит, по след ующие
перемещения мыши привод ят к перемещению фигуры, а при отпускании
кнопки мыши выбранная фигура о стается на новом месте. Если
указатель мыши не наход ится над какой-либо фигурой, значит, нажав
кнопку, пользователь выд еляет несколько фигур, по след ующие
перемещения мыши привод ят к изменению размера прямоугольника
выд еления, а при отпускании кнопки мыши фигуры внутри
прямоугольника выд еления становятся выд еленными. Изначальный код
выгляд ит примерно так:
SelectionTool
Figure selected;
public void mouseDown() {
selected = findFigure();
if (selected!= null)
select(selected);
}
public void mouseMove() {
if (selected!= null)
move(selected);
else
moveSelectionRectangle();
}
public void mouseUp() {
if (selected == null)
selectAll();
}
В глаза бро саются три похожих условных оператора (я же говорил,
что они плод ятся, как мухи). Что д елать, чтобы избавиться от них?
Созд аем встраиваемый объект, SelectionMode, облад ающий д вумя
реализациями: SingleSelection и MultipleSelection.
SelectionTool
SelectionMode mode;
public void mouseDown() {
selected = findFigure();
if (selected!= null)
mode = SingleSelection(selected);
else
mode = MultipleSelection();
}
public void mouseMove() {
mode.mouseMove();
}
public void mouseUp() {
mode.mouseUp();
}
В языках с явными интерфейсами вы обязаны реализовать интерфейс
с д вумя (или больше) встраиваемыми объектами.
Do'stlaringiz bilan baham: |