Вопрос

Можно ли сказать, что категории Objective-C являются реализацией шаблон дизайна посетителей?

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

Решение

Нет, категории Objective-C не являются реализацией шаблона посетителя.Категории на самом деле не имеют точного соответствия в мире шаблонов проектирования, поскольку техника внедрения методов в существующие классы без подклассов невозможна в большинстве языков.Я бы сказал, что это ближе к шаблон декоратора, но этот шаблон обычно реализуется с помощью композиции, т.е.обернув экземпляр объекта, который вы хотите «улучшить».

Шаблон посетителя полезен для инкапсуляции логики алгоритма, которую можно применять к различным объектам, структурам и т. д.Например, если вы хотите создать вывод HTML для графа объектов, вы можете (А) написать htmlString метод для каждого объекта и вызывать его для каждого объекта, или (Б) использовать шаблон посетителя и создать конкретного посетителя, который знает, как создавать выходные данные HTML для каждого узла, который он посещает.

Первый подход является более общим, и логика задачи T разбросана небольшими частями по классам X, Y и Z.Последний подход помещает весь связанный код в один объект посетителя, что упрощает обслуживание и предотвращает проблему «Я забыл этот класс...».Тем не менее, шаблон посетителя, возможно, несколько тяжеловесен для простых ситуаций — он действительно окупается, когда у вас есть несколько различных параллельных функций и вы хотите абстрагировать логику от классов, на которых эта функциональность выполняется.Например, вы можете реализовать других посетителей, которые производят вывод в формате PDF или RTF и т. д.Каждый посетитель может позаботиться о рекурсии и вызове собственных методов посещения в необходимом порядке, а отдельные посетители могут использовать совершенно отдельный порядок.

Следует отметить, что во многих языках шаблон посетителя использует перегрузку методов (то же имя, разные сигнатуры/аргументы).Поскольку Objective-C не допускает перегрузку методов, вы должны использовать отдельные имена методов, но на самом деле это может помочь избежать ошибок, вызванных незнанием, какая перегрузка вызывается.

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

Категории можно использовать для реализации шаблона посетителя.

@protocol Visit
- (void)acceptVisitor:(MyVisitor *)visitor;
@end

@interface Foo (Visit) <Visit>
@end

@interface Bar (Visit) <Visit>
@end

@implementation MyVisitor

- (void)visit:(id)someObject {
    if ([someObject conformsToProtocol:@protocol(Visit)]) {
        [(id<Visit>)someObject acceptVisitor:self];
    }
}

- (void)visitFoo:(Foo *)foo { ... }

- (void)visitBar:(Bar *)bar { ... }

@end

@implementation Foo (Visit)
- (void)acceptVisitor:(MyVisitor *)visitor {
    [visitor visitFoo:self];
} 
@end

@implementation Bar (Visit)
- (void)acceptVisitor:(MyVisitor *)visitor {
    [visitor visitBar:Self];
}
@end

На мой взгляд, это более аккуратный дизайн, чем классический дизайн GoF Visitor, поскольку нет загрязнения общедоступных интерфейсов посещаемых классов, и все это может быть инкапсулировано в блоке компиляции класса посетителя.

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