pvllnspk
pvllnspk

Reputation: 5767

implementation of the "Template method pattern" in objective c

I know that Objective-C doesn't support abstract classes but it's nonetheless OO language (http://en.wikipedia.org/wiki/Objective-C). So I have several objects with the same methods except one, and I would like to follow the DRY principle and don't repeat a lot of the same code in several classes. What's the best way to do it?

Upvotes: 0

Views: 563

Answers (1)

Jeffery Thomas
Jeffery Thomas

Reputation: 42588

So I have several object with the same methods except one, so I would like to follow DRY principle and don't repeat a lot of the same code in one place.

I assume you mean "I have several classes with the same methods except one".


It depends on how formal you want to be about the whole thing. It all starts with a base class that has all the common methods. I will call that @interface A : NSObject.

Sub-classes of A will inherit from A

  • @interface A1 : A
  • @interface A2 : A

The sub-class that needs the unique method I will call B

  • @interface B : A

You can test at run-time to see if objects of class A are able to perform that unique method.

A *a = ...
if ([a respondsToSelector:@selector(uniqueMethod)])
    [(id)a uniqueMethod];

This is a very informal method and may cause maintenance issues in the future if other classes start implementing the unique method.

Another option is to check for class membership.

A *a = ...
if ([a isKindOfClass:[B class]])
    [(B *)a uniqueMethod];

This is still informal, but provides better protection of future changes. It also limits future flexibility, because other instances of A may need to use the unique method in the future, but then must be refactored into sub-classes of B.

The formal way to do this is protocols. I will create protocols for A and B that I will call AP and BP. This changes the interface for A and B.

  • @interface A : NSObject <AP>
  • @interface B : A <BP>

Now the test becomes a matter for conformance.

A *a = ...
if ([a  conformsToProtocol:@protocol(BP)])
    [(id<BP>)a uniqueMethod];

This allows for protection and flexibility, but is more work to maintain when future changes are needed.

Hope that helps.

Upvotes: 1

Related Questions