什么是“模板方法模式”?在可可中与对象 C ? (语言比较思维)

发布于 2024-10-09 16:13:58 字数 166 浏览 6 评论 0原文

这是模板方法模式,Java和C++可以通过虚函数轻松实现它。用Object C 来实现这个模式怎么样? cocoa touch (iOS) 有什么例子吗?

Here is template method pattern , Java and C++ can implement it easily with virtual function. How about Object C to implement this pattern ? Any example in cocoa touch (iOS) ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千笙结 2024-10-16 16:13:58

作为 jer 已经指出,所有Objective-C方法本质上都是虚拟的。这是该语言的一个特性,与其他类 C 语言不太吻合。话虽这么说,模板方法模式的基础知识仍然可以在 Objective-C 中通过“手动”强制子类实现某些功能来实现。例如(使用链接的维基百科文章中的约定):

@interface Game
{
    int playersCount;
}
- (void)playOneGame:(int)numPlayers;
// "virtual" methods: 
- (void)initializeGame;
- (void)makePlay:(int)player;
- (BOOL)endOfGame;
- (void)printWinner;
@end

@implementation Game
- (void)initializeGame         { NSAssert(FALSE); }
- (void)makePlay:(int player)  { NSAssert(FALSE); }
- (BOOL)endOfGame              { NSAssert(FALSE); return 0; }
- (void)printWinner            { NSAssert(FALSE); }
- (void)playOneGame:(int)numPlayers
{
    //..
}
@end

上面的代码通过在调用基类实现之一时抛出异常来强制 Game 的子类覆盖“虚拟”方法。实际上,这将测试从编译器阶段(就像在 C++ 或 Java 中一样)转移到运行时阶段(在 Objective-C 中经常完成类似的事情)。

如果您确实想要强制执行不允许子类重写playOneGame:方法的规则,您可以尝试(*)从内部验证正确的实现>init 方法:

@implementation Game
...
- (void)init
{
    if ((self = [super init]) == nil) { return nil; }

    IMP my_imp = [Game instanceMethodForSelector:@selector(playOneGame:)];
    IMP imp = [[self class] instanceMethodForSelector:@selector(playOneGame:)];
    NSAssert(imp == my_imp);

    return self;
}
...
@end

(*) 请注意,由于 Objective-C 的本质,此代码不会对重新实现 playOneGame: 的子类产生 100% 坚如磐石的防御将允许子类重写 instanceMethodForSelector: 以产生正确的结果。

As jer has already pointed out, all Objective-C methods are essentially virtual. It is a feature of the language which does not quite mesh with other C-like languages. That being said, the basics of the template method pattern can still be achieved in Objective-C, by "manually" forcing subclasses to implement certain functions. For example (using the convention in your linked Wikipedia article):

@interface Game
{
    int playersCount;
}
- (void)playOneGame:(int)numPlayers;
// "virtual" methods: 
- (void)initializeGame;
- (void)makePlay:(int)player;
- (BOOL)endOfGame;
- (void)printWinner;
@end

@implementation Game
- (void)initializeGame         { NSAssert(FALSE); }
- (void)makePlay:(int player)  { NSAssert(FALSE); }
- (BOOL)endOfGame              { NSAssert(FALSE); return 0; }
- (void)printWinner            { NSAssert(FALSE); }
- (void)playOneGame:(int)numPlayers
{
    //..
}
@end

The above code forces subclasses of Game to override the "virtual" methods by throwing an exception the moment one of the base class implementations is called. In effect, this moves the test from the compiler stage (as it would be in C++ or Java) and into the runtime stage (where similar things are often done in Objective-C).

If you really want to enforce the rule that subclasses are not allowed to override the playOneGame: method, you can attempt(*) to verify the correct implementation from within the init method:

@implementation Game
...
- (void)init
{
    if ((self = [super init]) == nil) { return nil; }

    IMP my_imp = [Game instanceMethodForSelector:@selector(playOneGame:)];
    IMP imp = [[self class] instanceMethodForSelector:@selector(playOneGame:)];
    NSAssert(imp == my_imp);

    return self;
}
...
@end

(*) Note that this code does not result in a 100% rock-solid defense against subclasses which re-implement playOneGame:, since the very nature of Objective-C would allow the subclass to override instanceMethodForSelector: in order to produce the correct result.

静若繁花 2024-10-16 16:13:58

在 Objective-C 中,所有方法都类似于 C++ 虚拟方法。

In Objective-C all methods are akin to C++ virtual methods.

谢绝鈎搭 2024-10-16 16:13:58

在 Objective-C 模板方法模式中,当你有一个算法的骨架但可以用不同的方式实现时,就会使用模板方法模式。模板方法定义了执行算法的步骤,并且它可以提供可能对所有或某些子类通用的默认实现。

让我们举个例子,但先看一下图片

在此处输入图像描述

 @interface Worker : NSObject

- (void) doDailyRoutine;
- (void) doWork; // Abstract
- (void) comeBackHome; 
- (void) getsomeSleep;
@end

@implementation Worker

- (void) doDailyRoutine {
  [self doWork];
  [self comeBackHome];
  [self getsomeSleep];
  }

 - (void) doWork { [self doesNotRecognizeSelector:_cmd]; }
 - (void) comeBackHome { [self doesNotRecognizeSelector:_cmd]; }
 - (void) getsomeSleep { [self doesNotRecognizeSelector:_cmd]; }
 // [self doesNotRecognizeSelector:_cmd] it will force to call the subclass          Implementation
@end

@interface Plumber : Worker
@end

@implementation Plumber

- (void) doWork { NSLog(@“Plumber Work"); }

@end
@interface Electrician : Worker

@end

@implementation Electrician

- (void) doWork { NSLog(@“Electrician Work"); }

@end
@interface Cleaner : Worker

@end

@implementation Cleaner

- (void) doWork { NSLog(@“Cleaner Work"); }

@end

在此示例中,dowork() 是一个抽象函数,应由所有子类实现,并且此模式主要用于 Cocoa 框架中。

希望它能帮助您理解“模板方法模式”。

In Objective-C Template Method Pattern is Used When you have a Skeleton of an Algorithm but it can be Implemented in different ways. Template method defines the steps to execute an algorithm and it can provide default implementation that might be common for all or some of the subclasses.

Let's take an example but First Look at the Picture

enter image description here

 @interface Worker : NSObject

- (void) doDailyRoutine;
- (void) doWork; // Abstract
- (void) comeBackHome; 
- (void) getsomeSleep;
@end

@implementation Worker

- (void) doDailyRoutine {
  [self doWork];
  [self comeBackHome];
  [self getsomeSleep];
  }

 - (void) doWork { [self doesNotRecognizeSelector:_cmd]; }
 - (void) comeBackHome { [self doesNotRecognizeSelector:_cmd]; }
 - (void) getsomeSleep { [self doesNotRecognizeSelector:_cmd]; }
 // [self doesNotRecognizeSelector:_cmd] it will force to call the subclass          Implementation
@end

@interface Plumber : Worker
@end

@implementation Plumber

- (void) doWork { NSLog(@“Plumber Work"); }

@end
@interface Electrician : Worker

@end

@implementation Electrician

- (void) doWork { NSLog(@“Electrician Work"); }

@end
@interface Cleaner : Worker

@end

@implementation Cleaner

- (void) doWork { NSLog(@“Cleaner Work"); }

@end

In this example dowork() is an Abstract function which should be implemented by all the subclasses and this pattern is largely used in Cocoa Frameworks.

Hope it will help you to Understand the "Template Method Pattern".

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文