
//Prototype
@protocol Shape <NSObject>
@property (nonatomic, copy) NSString *color;
- (id<Shape>)clone;
@end
//ConcretePrototype
@interface Square : NSObject <Shape>
- (instancetype)initWithColor:(NSString *)color;
@end
@implementation Square
//@synthesize is needed: the property comes from the protocol,
//not from @interface
@synthesize color;
- (instancetype)initWithColor:(NSString *)value {
self = [super init];
if (self) {
color = [value copy];
}
return self;
}
- (id<Shape>)clone {
return [[Square alloc] initWithColor:color];
}
@end
//Client
@interface ShapeMaker : NSObject
- (instancetype)initWithShape:(id<Shape>)shape;
- (id<Shape>)makeShape;
@end
@implementation ShapeMaker {
id<Shape> _shape;
}
- (instancetype)initWithShape:(id<Shape>)shape {
self = [super init];
if (self) {
_shape = shape;
}
return self;
}
- (id<Shape>)makeShape {
return [_shape clone];
}
@end
Square *square = [[Square alloc] initWithColor:@"Red"];
ShapeMaker *maker = [[ShapeMaker alloc] initWithShape:square];
id<Shape> square1 = [maker makeShape];
Square *square2 = (Square *)[maker makeShape];
NSLog(@"%@", square1.color);
NSLog(@"%@", square2.color);
Описывает виды создаваемых объектов с помощью прототипа и создает новые объекты путем его копирования.Read moreЗадача. В графическом редакторе есть палитра готовых фигур, и у каждой свои цвет, размер и рамка. Когда пользователь перетаскивает фигуру на страницу, программа должна сделать точно такую же новую фигуру. Если код пользуется конструктором, ему приходится знать точный класс и вручную копировать каждую настройку. Тогда каждый новый вид фигуры меняет этот код. Идея. Прототип - это готовый объект, который умеет себя копировать. У него один метод копирования, часто он называется clone. Клиент держит прототип и просит у него копии. Конкретный класс клиент не называет и не знает, какие поля копируются. Копия начинает с теми же данными, что у оригинала, а дальше два объекта живут независимо. Как читать пример. Прототип - это фигура с одним значением, например цветом или числом сторон. В большинстве языков объект-клиент держит один прототип, а новые фигуры получает только одним способом - просит у него копию. Вывод показывает, что у копий то же значение, что у прототипа. Некоторые примеры показывают ещё, что копия - отдельный объект или что изменение копии не трогает прототип. В языках, где значения никогда не меняются, ничего не копируется: новый вариант - это тот же образец с одним изменённым полем. Когда применять. Прототип нужен, когда объект дорого подготовить, а похожих объектов требуется много. Он помогает и тогда, когда класс создаваемого объекта становится известен только во время работы программы. Для простых объектов с немногими полями он ни к чему: конструктор проще. Частая ошибка. Написать метод копирования только в базовом классе, так что он всегда создаёт базовый объект. Копия конкретного прототипа тогда теряет свой класс. Каждый конкретный прототип должен создавать объект своего класса. |