Предположим, я проектировал компонент, представляющий ручки на элементе управления пользовательского интерфейса, для изменения его размера.
![Control](https://i.stack.imgur.com/Hgplp.jpg)
теперь очевидно, что каждая ручка не совсем одинакова с точки зрения поведения, например, верхняя левая ручка должна будет отображать курсор мыши с северо-запада на юго-восток, и ее перетаскивание изменит размер элемента управления, тогда как верхняя средняя ручка требует чтобы показать курсор мыши с севера на юг и перетаскивание его позволит вам только изменить высоту.
С точки зрения реализации существует два основных подхода: -
(1) конструктор, который требует, чтобы вы передали информацию о том, какой тип захвата вы разрабатываете, а затем содержали огромный оператор switch для определения фактического поведения захвата, например, так:
- initWithGripType(int)gripType
{
switch(gripType {
case TOP_MIDDLE_GRIP:
cursorType = northSouthCursor;
draggedMovement = upDown;
break;
case TOP_LEFT_GRIP:
cursorType = northWestSouthEastCursor;
draggedMovement = upDownLeftRight;
break;
...
...
...
}
}
(2) имеет базовый класс сцепления, который определяет общие атрибуты. например, рисовать ручку одинаково, независимо от того, какая она ручка. И тогда подклассы для каждого типа захвата выглядят так: -
@interface Grip : NSObject {
NSCursor _cursorType;
int _draggedMovement;
}
// force init to be unavilable for base class
- (id)init __attribute__((unavailable("Instantiate subclass instead.")));
- (void)drawGrip;
@end;
@interface GripTopLeft : Grip {
}
- (id)init;
@end;
@interface GripBottomLeft : Grip {
}
- (id)init;
@end;
...
...
...
Преимущество второго подхода заключается в том, что мне не нужно поддерживать какие-либо операторы switch и я могу добавлять новые типы ручек по желанию. Недостатком является то, что если у меня много типов ручек, каждый из них теперь является отдельным исходным файлом и файлом заголовка.
Есть ли третий подход?