Подтвердить что ты не робот

Factory (шаблон проектирования) в Objective C

Я пытаюсь создать factory (шаблон проектирования) в Objective C Поэтому я делаю что-то вроде:

+ (Car *)createCar:(int)color {
    if (color == 1) {
        return [CarFactory createBlueCar];
    } else if (color == 2) {
        return [CarFactory createRedCar];
    } else {
        return nil;
    }
}

+ (Car *)createBlueCar {
    // ...
}

+(Car*)createRedCar{
    // ...
}

Однако я не хочу, чтобы createBlueCar и createRedCar были доступны для публики, и если я не определяю их в файле .h, тогда я получаю предупреждение о отсутствующем определении.

Я бывший разработчик Java и новичок в Objective-C. Так что это может быть просто плохая практика. Если так, то это хорошая практика.

4b9b3361

Ответ 1

Лучший способ сделать это - расширение класса.

.h

@interface MyClass : NSObject
@property(readonly) BOOL publiclyReadOnlyPrivatelyWritableFlag;
+ (id) myExposedFactoryMethod;
@end

ого

#import "MyClass.h"

@interface MyClass ()
@property(readwrite) BOOL publiclyReadOnlyPrivatelyWritableFlag;
+ (id) privateMethod1;
+ (id) privateMEthod2;
@end

@implementation MyClass
@synthesize publiclyReadOnlyPrivatelyWritableFlag; // no ivar -- only works in 64 bit and iPhone
+ (id) myExposedFactoryMethod
{
    ...
    [self privateMethod1];
    ...
}

+ (id) privateMethod1;
{
    return ...
}

+ (id) privateMEthod2;
{
    return ...
}
@end

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

Обратите внимание, что расширение класса позволяет вам обновить свойство readonly до свойства readwrite в соответствии с приведенным выше примером.

Ответ 2

Я думаю, вы можете добавить их в класс, используя objective-c category в файле реализации (а не в интерфейсе) как способ эмуляции частных методов, если вы хотите "скрыть" их от пользователей вашего класса.

Обратите внимание, что вы больше не будете рекламировать методы для клиентов вашего класса, они все равно смогут использовать их, если они используют правильные селектора. Кроме того, они могут всегда использовать что-то вроде classdump, чтобы восстановить полный интерфейс для вашего класса, чтобы ваши методы никогда не были действительно скрыты.

См. этот вопрос для дальнейших примеров создания методов "private" под objective-c.

Ответ 3

Вы можете создать частную статическую функцию

@implementation Car 

static createBlueCar () {
  ....
}

+(Car*) createCar:(int) color{
   if (color==1) {
     return createBlueCar();
   } ...
}

@end

но нет, вы не можете создать истинный частный член. (Вы можете ссылаться на некоторые соглашения, например +(Car*)private_createCar в частной категории, чтобы препятствовать его использованию.)