Категории Objective-C == шаблон посетителя? - PullRequest
6 голосов
/ 26 августа 2009

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

Ответы [ 2 ]

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

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

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

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

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

2 голосов
/ 28 февраля 2011

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

@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

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

...