MST

星途 面试题库

面试题:Objective-C中访问者模式的基本实现

请描述在Objective-C中实现访问者模式的基本步骤,包括定义访问者和元素的相关类,以及如何在客户端代码中使用它们。同时,给出一个简单的示例代码框架,说明元素类和访问者类的关键方法。
40.6万 热度难度
编程语言Objective-C

知识考点

AI 面试

面试题答案

一键面试

1. 定义元素接口(Element Interface)

定义一个接受访问者的方法 accept:,所有具体元素类都要实现这个接口。

@protocol Element <NSObject>
- (void)accept:(id<Visitor>)visitor;
@end

2. 定义具体元素类(Concrete Element Classes)

每个具体元素类实现 Element 接口的 accept: 方法,并调用访问者的相应访问方法。

@interface ConcreteElementA : NSObject <Element>
- (void)operationA;
@end

@implementation ConcreteElementA
- (void)operationA {
    NSLog(@"ConcreteElementA: operationA");
}

- (void)accept:(id<Visitor>)visitor {
    [visitor visitConcreteElementA:self];
}
@end

@interface ConcreteElementB : NSObject <Element>
- (void)operationB;
@end

@implementation ConcreteElementB
- (void)operationB {
    NSLog(@"ConcreteElementB: operationB");
}

- (void)accept:(id<Visitor>)visitor {
    [visitor visitConcreteElementB:self];
}
@end

3. 定义访问者接口(Visitor Interface)

为每个具体元素类定义一个访问方法。

@protocol Visitor <NSObject>
- (void)visitConcreteElementA:(ConcreteElementA *)elementA;
- (void)visitConcreteElementB:(ConcreteElementB *)elementB;
@end

4. 定义具体访问者类(Concrete Visitor Classes)

实现访问者接口中的所有访问方法。

@interface ConcreteVisitor1 : NSObject <Visitor>
- (void)visitConcreteElementA:(ConcreteElementA *)elementA {
    [elementA operationA];
    NSLog(@"ConcreteVisitor1 visited ConcreteElementA");
}

- (void)visitConcreteElementB:(ConcreteElementB *)elementB {
    [elementB operationB];
    NSLog(@"ConcreteVisitor1 visited ConcreteElementB");
}
@end

@interface ConcreteVisitor2 : NSObject <Visitor>
- (void)visitConcreteElementA:(ConcreteElementA *)elementA {
    [elementA operationA];
    NSLog(@"ConcreteVisitor2 visited ConcreteElementA");
}

- (void)visitConcreteElementB:(ConcreteElementB *)elementB {
    [elementB operationB];
    NSLog(@"ConcreteVisitor2 visited ConcreteElementB");
}
@end

5. 客户端代码使用

创建具体元素和具体访问者,并调用元素的 accept: 方法。

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        ConcreteElementA *elementA = [[ConcreteElementA alloc] init];
        ConcreteElementB *elementB = [[ConcreteElementB alloc] init];

        ConcreteVisitor1 *visitor1 = [[ConcreteVisitor1 alloc] init];
        ConcreteVisitor2 *visitor2 = [[ConcreteVisitor2 alloc] init];

        [elementA accept:visitor1];
        [elementB accept:visitor1];

        [elementA accept:visitor2];
        [elementB accept:visitor2];
    }
    return 0;
}

关键方法总结:

  • 元素类关键方法accept: 方法,用于接受访问者并调用访问者相应的访问方法。
  • 访问者类关键方法:针对每个具体元素类的访问方法,如 visitConcreteElementA:visitConcreteElementB:,在这些方法中定义对具体元素的操作。