面试题答案
一键面试1. 定义备忘录类(Memento)
- 职责:用于保存绘图对象(图形)的状态。
@interface DrawingMemento : NSObject
@property (nonatomic, strong) id state; // 保存图形状态,不同图形状态类型不同
- (instancetype)initWithState:(id)state;
@end
@implementation DrawingMemento
- (instancetype)initWithState:(id)state {
self = [super init];
if (self) {
_state = state;
}
return self;
}
@end
2. 定义绘图对象类(Originator)
- 职责:创建备忘录以保存自身状态,从备忘录中恢复自身状态。
@interface DrawingObject : NSObject
@property (nonatomic, strong) id currentState; // 当前图形状态
- (DrawingMemento *)saveState;
- (void)restoreState:(DrawingMemento *)memento;
@end
@implementation DrawingObject
- (DrawingMemento *)saveState {
return [[DrawingMemento alloc] initWithState:self.currentState];
}
- (void)restoreState:(DrawingMemento *)memento {
self.currentState = memento.state;
}
@end
3. 定义负责人类(Caretaker)
- 职责:负责管理备忘录,维护一个备忘录的栈,用于实现撤销操作。
@interface DrawingCaretaker : NSObject
@property (nonatomic, strong) NSMutableArray<DrawingMemento *> *mementoStack;
- (void)pushMemento:(DrawingMemento *)memento;
- (DrawingMemento *)popMemento;
@end
@implementation DrawingCaretaker
- (instancetype)init {
self = [super init];
if (self) {
_mementoStack = [NSMutableArray array];
}
return self;
}
- (void)pushMemento:(DrawingMemento *)memento {
[self.mementoStack addObject:memento];
}
- (DrawingMemento *)popMemento {
if (self.mementoStack.count > 0) {
DrawingMemento *memento = self.mementoStack.lastObject;
[self.mementoStack removeLastObject];
return memento;
}
return nil;
}
@end
4. 性能和内存管理
- 性能:
- 备忘录栈使用
NSMutableArray
,添加和删除操作平均时间复杂度为 O(1),保证了撤销操作的高效性。 - 对于不同图形对象,状态保存与恢复操作尽量做到原子化,减少不必要的计算开销。
- 备忘录栈使用
- 内存管理:
DrawingMemento
、DrawingObject
和DrawingCaretaker
都遵循ARC(自动引用计数)规则,对象创建和销毁由系统自动管理,避免了手动内存管理的错误。- 当不再需要保存的状态时(例如用户清空绘图历史),可以通过清空
DrawingCaretaker
的备忘录栈来释放内存。
5. 不同图形对象的状态保存与恢复
- 不同图形对象(如圆形、矩形等)可以继承自
DrawingObject
类。 - 对于每个具体图形对象,在
saveState
方法中保存其特定的状态属性(如圆形的半径、矩形的长宽等),在restoreState
方法中恢复这些属性。例如:
@interface Circle : DrawingObject
@property (nonatomic, CGFloat) radius;
@end
@implementation Circle
- (DrawingMemento *)saveState {
NSMutableDictionary *stateDict = [NSMutableDictionary dictionary];
stateDict[@"radius"] = @(self.radius);
return [[DrawingMemento alloc] initWithState:stateDict];
}
- (void)restoreState:(DrawingMemento *)memento {
NSDictionary *stateDict = memento.state;
self.radius = [stateDict[@"radius"] floatValue];
}
@end
同样,矩形等其他图形对象也可类似实现。这样就可以实现不同图形对象状态的保存与恢复,同时利用备忘录模式实现绘图应用的撤销功能。