When to use (or not use) a delegate - objective-c

This is a pretty general question, but I was wondering today about delegates. At this point I don't really have a specific time I do use them or don't use them - aside from obvious cases, like passing selections from a picker or tableview stuff. For example, if there's a situation where I can pass a reference to an object around and use that to call methods, is there a reason to implement a delegate? In summary, what is the delegate pattern intended for use in and when is it better to NOT use it?
Thanks for the quick and comprehensive answers! They were all extremely helpful.

The advantage of the delegate pattern is loose coupling between the delegating object and its delegate. Loose coupling improves a class's reusability in other contexts.
The delegating object doesn't have to know anything about the object it communicates with (aside from the requirement that it implement the delegate protocol) – especially not its class or what methods it has. If you later want to reuse your component in a different context or have it communicate with another object of a different class, all this object has to do is implement the delegate protocol. The delegating object does not have to be changed at all.
There is also a downside to this, of course, and that is that a bit more code is required and the code you write is not as explicit and therefore may be a bit harder to understand. Whether this (generally small) tradeoff is worth it depends on your use case. If the two objects are tightly coupled anyway and the probability of reuse in the future is low, using the delegate pattern might be overkill.

See this discussion
A delegate allows one object to send messages to another object when an event happens.
Pros
Very strict syntax. All events to be heard are clearly defined in
the delegate protocol.
Compile time Warnings / Errors if a method is not implemented as it should be by a delegate.
Protocol defined within the scope of the controller only.
Very traceable, and easy to identify flow of control within an application.
Ability to have multiple protocols defined one controller, each with different delegates.
No third party object required to maintain / monitor the communication process.
Ability to receive a returned value from a called protocol method. This means that a delegate can help provide information back
to a controller.
Cons
Many lines of code required to define: 1. the protocol definition, 2. the delegate property in the controller, and 3. the implementation of the delegate method definitions within the delegate itself.
Need to be careful to correctly set delegates to nil on object deallocation, failure to do so can cause memory crashes by calling methods on deallocated objects.
Although possible, it can be difficult and the pattern does not really lend itself to have multiple delegates of the same protocol in a controller (telling multiple objects about the same event)

The "use case" for delegation is pretty much the same as for inheritance, namely extending a class behavior in a polymorphic way.
This is how the wikipedia defines delegation:
In software engineering, the delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object. There is an Inversion of Responsibility in which a helper object, known as a delegate, is given the responsibility to execute a task for the delegator. The delegation pattern is one of the fundamental abstraction patterns that underlie other software patterns such as composition (also referred to as aggregation), mixins and aspects.
There are, obviously, many differences between delegation and inheritance, but the biggest one is, IMO, that inheritance is a fixed (aka, compile-time) relationship between two classes, while delegation can be defined at run-time (in languages that support this). On the other hand, inheritance offers better support for polymorphism.
Delegation is a huge topic (as inheritance is), and you can read a lot about it. In the end, deciding whether using delegation or inheritance comes down to deciding whether you want an "is-a" or and "has-a" relationship, so it is not so easy to list guidelines for choosing that.
For me, basically, the decision to create a delegate comes from the observation that:
my code presents a set of homogeneous behaviors (homogeneous here means that can be recognized as having a common "nature");
those behaviors might be be "customized" for particular cases (like in, replaced by alternative behaviors).
This is my personal view and a description of the way I get to identify "delegation" patterns. It has probably much to do with the fact that my programming discipline is strongly informed by the principle of refactoring.
Really, IMO, delegation is a way to define "customization" points for your class. As an example, if you have some kind of abstract workflow, where at each step you take some action depending on certain condition; and furthermore those concrete actions could be replaced by other of another kind, then I see there the chance of reuse through delegation.
Hope this helps.

Related

Why subclassing [duplicate]

After reading lots of blogs, forum entries and several Apple docs, I still don't know whether extensive subclassing in Objective-C is a wise thing to do or not.
Take for example the following case:
Say I'm developing a puzzle game which
has a lot of elements. All of those
elements share a certain amount of the
same behaviour. Then, within my
collection of elements, different
groups of elements share equal
behaviour, distinguishing groups from
groups, etc...
So, after determining what inherits
from what, I decided to subclass out
of oblivion. And why shouldn't I?
Considering the ease tweaking general
behaviour takes with this model, I
think I accomplished something OOP is
meant for.
But, - and this is the source of my question - Apple mentions using delegates, data source methods, and informal protocols in favour of subclassing. It really boggles my mind why?
There seem to be two camps. Those in favor of subclassing, those in fafor of not. It depends on personal taste apparently. I'm wondering what the pros and cons are of subclassing massively and not subclassing massively?
To wrap it up, my question is simple: Am I right? And why or why not?
Delegation is a means of using the composition technique to replace some aspects of coding you would otherwise subclass for. As such, it boils down to the age old question of the task at hand needing one large thing that knows how to do a lot, or if you have a loose network of specialized objects (a very UNIX sort of model of responsibility).
Using a combination of delegates and protocols (to define what the delegates are supposed to be able to do) provides a great deal of flexibility of behavior and ease of coding - going back to that Liskov substitution principle, when you subclass you have to be careful you don't do anything a user of the whole class would find unexpected. But if you are simply making a delegate object then you have much less to be responsible for, only that the delegate methods you implement do what that one protocol calls for, beyond that you don't care.
There are still many good reasons to use subclasses, if you truly have shared behavior and variables between a number of classes it may make a lot of sense to subclass. But if you can take advantage of the delegate concept you'll often make your classes easier to extend or use in ways you the designer may not have expected.
I tend to be more of a fan of formal protocols than informal ones, because not only do formal protocols make sure you have the methods a class treating you as a delegate expect, but also because the protocol definition is a natural place to document what you expect from a delegate that implements those methods.
Personally, I follow this rule: I can create a subclass if it respects the Liskov substitution principle.
Subclassing has it's benefits, but it also has some drawbacks. As a general rule, I try to avoid implementation inheritance and instead use interface inheritance and delegation.
One of the reasons I do this is because when you inherit implementation, you can wind up with problems if you override methods but don't adhere to their (sometimes undocumented contract). Additionally, I find walking class hierarchies with implementation inheritance difficult because methods can be overridden or implemented at any level. Finally, when subclassing you can only widen an interface, you can't narrow it. This leads to leaky abstractions. A good example of this is java.util.Stack which extends java.util.Vector. I shouldn't be able to treat a stack as a Vector. Doing so only allows the consumer to run around the interface.
Others have mentioned the Liskov Substitution Principle. I think that using that would have certainly cleared up the java.util.Stack problem but it can also lead to very deep class hierarchies in order to put ensure that classes get only the methods they are supposed to have.
Instead, with interface inheritance there is essentially no class hierarchy because interfaces rarely need to extend one another. The classes simply implement the interfaces that they need to and can therefore be treated in the correct way by the consumer. Additionally, because there is no implementation inheritance, consumers of these classes won't infer their behavior due to previous experience with a parent class.
In the end though, it doesn't really matter which way you go. Both are perfectly acceptable. It's really more a matter of what you're more comfortable with and what the frameworks that you're working with encourage. As the old saying goes: "When in Rome do as Romans do."
There's nothing wrong with using inheritance in Objective-C. Apple uses it quite a bit. For instance, in Cocoa-touch, the inheritance tree of UIButton is UIControl : UIView : UIResponder : NSObject.
I think Martin hit on an important point in mentioning the Liskov substitution principle. Also, proper use of inheritance requires that the implementer of the subclass has a deep knowledge of the super class. If you've ever struggled to extend a non-trivial class in a complex framework, you know that there's always a learning curve. In addition, implementation details of the super class often "leak through" to the subclass, which is a big pain in the #$& for framework builders.
Apple chose to use delegation in many instances to address these problems; non-trivial classes like UIApplication expose common extension points through a delegate object so most developers have both an easier learning curve and a more loosely coupled way to add application specific behavior -- extending UIApplication directly is rarely necessary.
In your case, for your application specific code, use which ever techniques you're comfortable with and work best for your design. Inheritance is a great tool when used appropriately.
I frequently see application programmers draw lessons from framework designs and trying to apply them to their application code (this is common in Java, C++ and Python worlds as well as Objective-C). While it's good to think about and understand the choices framework designers made, those lessons don't always apply to application code.
In general you should avoid subclassing API classes if there exist delegates, etc that accomplish what you want to do. In your own code subclassing is often nicer, but it really does depend on your goals, eg. if you're providing an API you should provide a delegate based API rather than assuming subclassing.
When dealing with APIs subclassing has more potential bugs -- eg. if any class in the class hierarchy gets a new method that has the same name as your addition you make break stuff. And also, if you're providing a useful/helper type function there's a chance that in the future something similar will be added to the actual class you were subclassing, and that might be more efficient, etc but your override will hide it.
Please read the Apple documentation "Adding behavior to a Cocoa program"!. Under "Inheriting from a Cocoa class" section, see the 2nd paragraph. Apple clearly mentions that Subclassing is the primary way of adding application specific behavior to the framework (please note, FRAMEWORK).
MVC pattern does not completely disallow the use of subclasses or subtypes. Atleast I have not seen this recommendation from either Apple or others (if I have missed please feel free to point me to the right source of information about this). If you are subclassing api classes only within your application, please go ahead, no one's stopping you but do take care that it does not break the behavior of the class/api as a whole. Subclassing is great way of extending the framework api's functionality. We see a lot of subclassing within the Apple IOS framework APIs too.
As a developer one has to take care the implementation is well documented and not duplicated accidentally by another developer. Its another ball game altogether if your application is a set of API classes that you plan to distribute as reusable component.
IMHO, rather than asking around what the best practice is, first read the related documentation thoroughly, implement and test it. Make your own judgement. You know best about what you're up to.
It's easy for others (like me and so many others) to just read stuff from different sources on the Net and throw around terms. Be your own judge, it has worked for me so far.
I really think it depends on what you're trying to do. If the puzzle game you describe in the example really does have a set of unique elements that share common attributes, and there's no provided classes - say, for example, "NSPuzzlePiece" - that fit your needs, then I don't see a problem with subclassing extensively.
In my experience, delegates, data source methods, and informal protocols are much more useful when Apple has provided a class that already does something close to what you want it to do.
For example, say you're building an app that uses a table. There is (and I speak here of the iPhone SDK, since that's where I have experience) a class UITableView that does all the little niceties of creating a table for interaction with the user, and it's much more efficient to define a data source for an instance of UITableView than it is to completely subclass UITableView and redefine or extend its methods to customize its behavior.
Similar concepts go for delegates and protocols. If you can fit your ideas into Apple's classes, then it's usually easier (and will work more smoothly) to do so and use data source, delegates, and protocols than it is to create your own subclasses. It helps you avoid extra work and wasting time, and is usually less error-prone. Apple's classes have taken care of the business of making functions efficient and debugging; the more you can work with them, the fewer mistakes your program will have in the long run.
my impression of ADC's emphasis 'against' subclassing has more to do with the legacy of how the operating system has evolved... back in the day (Mac Classic aka os9) when c++ was the primary interface to most of the mac toolbox, subclassing was the de-facto standard in order for a programmer to modify the behaviour of commonplace OS features (and this was indeed sometimes a pain in the neck and meant that one had to be very careful that any and all modifications behaved predictably and didn't break any standard behaviour).
this being said, MY IMPRESSION of ADC's emphasis against subclassing is not putting forth a case for designing an application's class hierarchy without inheritance, BUT INSTEAD to point out that in the new way of doing things (ie OSX) there are in most cases more appropriate means to go about customizing standard behavior without needing to subclass.
So, by all means, design your puzzle program's architecture as robustly as you can, leveraging inheritance as you see fit!
looking forward to seeing your cool new puzzle application!
|K<
Apple indeed appears to passively discourage subclassing with Objective-C.
It is an axiom of OOP design to Favor composition over implementation.

Standard delegate pattern seems at odds with delegate purpose

If I follow any of a number of examples available on the web, I see a common theme emerge with the delegate pattern:
myClass.delegate = self;
From what I read, delegation is supposed to uncouple behavior, but allow interaction between classes, however, only assigning a single delegate seems to be 100% at odds with this behavior.
I have a web dev background, and I am intimately familiar with pub/sub patterns, but what I'm trying to wrap my head around is why I would only allow a single delegate (self) to be able to act on whatever happens in myClass. That would seem to ruin the entire point of delegation.
Maybe I'm misunderstanding something, or maybe this is only the simplest form of delegation, but could someone please explain how statically assigning (in the classic sense) one class to another's delegate decouples behavior in any meaningful way.
Bonus: Perhaps a way to allow multiple classes to act on a delegation.
The delegate asserts additional control over the delegated class. The most simple example is windowShouldClose: method in the NSWindowDelegate protocol. The class delegate gets a chance to proactively override closing the window in NSWindow. If multiple delegates were allowed, multiple delegates could supply conflicting orders which would be an undesirable result.
Delegation allows you to customize behavior without subclassing. Because a class can implement many delegate protocols, it is a key part of the MVC programming model in Objective-C. Delegation allows you to create one class as a "Controller" of multiple other classes.
For acting reactively to what happens to the class, you use a pub/sub model of key value observing. For example, NSOperationQueue has an observable property operationCount to let you react to changes in the number of operations in the queue.
It decouples behavior in the sense that the delegator needn't know anything at all about the delegate other than that it (possibly) responds to a certain set of methods. This makes it so that classes that have delegate can be used in entirely different codebases/situation without changes. It's particularly applicable when writing Framework classes that will be used by someone else, which is one reason you see it so much in the system frameworks.
One of the major uses of delegation is to allow customization of an object's behavior without subclassing. Take for example the NSWindowDelegate method -windowWillResize:toSize:, where the delegate can return a different size than the suggested one to implement custom sizing behavior. How would this scenario be handled with multiple delegates each returning a different value?
Of course, sometimes delegate methods are merely meant to inform the delegate that some particular event has occurred. In these cases, it is indeed reasonable for multiple objects to want to be notified. This is provided for in Objective-C/Cocoa by notifications (NSNotification), and Key Value Observing (KVO). You'll find plenty of cases in Cocoa where a delegate method also has a corresponding notification posted in case objects other than the delegate want to know about it (e.g. windowWillClose:/NSWindowWillCloseNotification).

Using Objective-C Introspection vs. Forcing Additional Message Override?

I have a base class which adds some functionality to a number of derived classes in my app.
One of these features is only used by some subclasses.
Currently I'm using a method which returns a BOOL which defaults to NO to "short-circuit" this feature. Subclasses which want the feature must override this method and return YES.
This feature is only useful if you've also overridden at least one of two other methods.
I'd prefer to use class_copyMethodList to determine if the subclass implemented either of these two methods (instead of using the method which returns a BOOL).
What barriers/roadblocks/cons to this approach should I be aware of? Is there a standard implementation of this idiom which I can use?
If I may suggest an alternative approach, have you considered using -instanceMethodForSelector on the relevant subclass instance and comparing to the result on the base class?
That method returns an IMP, which is a C function pointer to the implementation for the given selector. So if the subclass has a different implementation from the base class, it'll return a different IMP.
EDIT: as discussed in the comments below, a further alternative is to declare a formal protocol that the sub classes may implement, and to use NSObject's -conformsToProtocol: to determine whether the protocol is implemented. Since conformsToProtocol returns whether the class has declared support for the protocol (in its #interface via the angle brackets syntax), that's a lot like adding a custom BOOL method that defaults to returning NO but without the syntactic and semantic overhead of adopting your own ad hoc solution.
I have a base class which adds some functionality to a number of derived classes in my app.
This sentence should cause you to rethink your design. A base class should never do anything to derived classes. It should be ignorant of its subclasses. (Class Clusters notwithstanding. That's a separate design approach and require the superclass to be aware in the construction, making it the Factory pattern, which is fine.)
One of these features is only used by some subclasses.
This is a strong indication of a "Square/Rectangle" mistake. In OOP (forget ObjC, this is just CS theory), a square is not a rectangle. You need to ensure that your types conform to Liskov's Substitution Principle. Again, this has nothing to do with any particular language; it's true of all OOP design. It may seem very "theoretical" but it will seriously screw up your implementation if you fail LSP, and you will chase subtle bugs for much longer than you like.
The pattern you probably want here is Decorator rather than subclassing. If you have some special functionality that exists on some classes, you want to encapsulate that functionality into a separate object and attach it to subclasses where it makes sense. Another possible pattern is Strategy (which is generally implemented as a "delegate" in ObjC, which is another way of thinking about Decorator). The point is that you don't want logic in the superclass that is only applicable to some subclasses. You want to put that logic into something that only exists in the appropriate subclasses.
If all of those things fail you, then I strongly recommend a simple (BOOL) function over anything that introspects the method implementations. That way is fragile because it relies on ever-deeper implementation details. respondsToSelector: is definitely better than testing instanceMethodForSelector:.

What is Encapsulation and how can it defend abstractions against corruption?

It's quoted from a report by Bjarne:
Encapsulation – the ability to provide
guarantees that an abstraction is used
only according to its specification –
is crucial to defend abstractions
against corruption.
Can someone explain this?
Thanks
Let's say you have a class with public methods that you must use to perform some action. The specification of the class say that, in order to do this action, you must configure the class in a specific way (call this method, set this property, etc).
The problem with situations like this is that it might not be clear what needs to happen or in what order. So the API for the class is hard to use and confusing for the majority of developers.
With encapsulation, you can "encapsulate" not just the class but the algorithms to use it within a second class. This second class sets up the original one, configures it, and manages its lifetime. It allows you to access the API without needing to know how to use it correctly, as the encapsulating class takes care of that. This is sometimes called the Facade pattern.
Your quote also says "is crucial to defend abstractions against corruption." What this means is that when you abstract some process into a class, different implementations of that process should not require the abstraction to be handled differently.
For example, you might have two implementations of a report writer class. You should be able to treat each of them exactly the same without ever knowing how they are implemented (the meaning of abstraction). However, if one cannot be run in a multithreaded apartment state (MTA), you have to "know", before you use it, that it is time to transition to an STA thread. This magical "knowing" is required by the implementation of the class. This is a "leaky abstraction."
With encapsulation, you could prevent this "leak" by, within the encapsulating class, making the transition to an STA thread within the encapsulation, preventing the abstraction from leaking details of its implementation.
It means that the object grant premission only to certain things it needs to expose, and deny you from using data it doen't want you to use.
The most classic example is properties:
Yout fields will be private (or protected).
If you would like to expose them for read or write, you'll add a getter\setter, accordingly.

Is subclassing in Objective-C a bad practice?

After reading lots of blogs, forum entries and several Apple docs, I still don't know whether extensive subclassing in Objective-C is a wise thing to do or not.
Take for example the following case:
Say I'm developing a puzzle game which
has a lot of elements. All of those
elements share a certain amount of the
same behaviour. Then, within my
collection of elements, different
groups of elements share equal
behaviour, distinguishing groups from
groups, etc...
So, after determining what inherits
from what, I decided to subclass out
of oblivion. And why shouldn't I?
Considering the ease tweaking general
behaviour takes with this model, I
think I accomplished something OOP is
meant for.
But, - and this is the source of my question - Apple mentions using delegates, data source methods, and informal protocols in favour of subclassing. It really boggles my mind why?
There seem to be two camps. Those in favor of subclassing, those in fafor of not. It depends on personal taste apparently. I'm wondering what the pros and cons are of subclassing massively and not subclassing massively?
To wrap it up, my question is simple: Am I right? And why or why not?
Delegation is a means of using the composition technique to replace some aspects of coding you would otherwise subclass for. As such, it boils down to the age old question of the task at hand needing one large thing that knows how to do a lot, or if you have a loose network of specialized objects (a very UNIX sort of model of responsibility).
Using a combination of delegates and protocols (to define what the delegates are supposed to be able to do) provides a great deal of flexibility of behavior and ease of coding - going back to that Liskov substitution principle, when you subclass you have to be careful you don't do anything a user of the whole class would find unexpected. But if you are simply making a delegate object then you have much less to be responsible for, only that the delegate methods you implement do what that one protocol calls for, beyond that you don't care.
There are still many good reasons to use subclasses, if you truly have shared behavior and variables between a number of classes it may make a lot of sense to subclass. But if you can take advantage of the delegate concept you'll often make your classes easier to extend or use in ways you the designer may not have expected.
I tend to be more of a fan of formal protocols than informal ones, because not only do formal protocols make sure you have the methods a class treating you as a delegate expect, but also because the protocol definition is a natural place to document what you expect from a delegate that implements those methods.
Personally, I follow this rule: I can create a subclass if it respects the Liskov substitution principle.
Subclassing has it's benefits, but it also has some drawbacks. As a general rule, I try to avoid implementation inheritance and instead use interface inheritance and delegation.
One of the reasons I do this is because when you inherit implementation, you can wind up with problems if you override methods but don't adhere to their (sometimes undocumented contract). Additionally, I find walking class hierarchies with implementation inheritance difficult because methods can be overridden or implemented at any level. Finally, when subclassing you can only widen an interface, you can't narrow it. This leads to leaky abstractions. A good example of this is java.util.Stack which extends java.util.Vector. I shouldn't be able to treat a stack as a Vector. Doing so only allows the consumer to run around the interface.
Others have mentioned the Liskov Substitution Principle. I think that using that would have certainly cleared up the java.util.Stack problem but it can also lead to very deep class hierarchies in order to put ensure that classes get only the methods they are supposed to have.
Instead, with interface inheritance there is essentially no class hierarchy because interfaces rarely need to extend one another. The classes simply implement the interfaces that they need to and can therefore be treated in the correct way by the consumer. Additionally, because there is no implementation inheritance, consumers of these classes won't infer their behavior due to previous experience with a parent class.
In the end though, it doesn't really matter which way you go. Both are perfectly acceptable. It's really more a matter of what you're more comfortable with and what the frameworks that you're working with encourage. As the old saying goes: "When in Rome do as Romans do."
There's nothing wrong with using inheritance in Objective-C. Apple uses it quite a bit. For instance, in Cocoa-touch, the inheritance tree of UIButton is UIControl : UIView : UIResponder : NSObject.
I think Martin hit on an important point in mentioning the Liskov substitution principle. Also, proper use of inheritance requires that the implementer of the subclass has a deep knowledge of the super class. If you've ever struggled to extend a non-trivial class in a complex framework, you know that there's always a learning curve. In addition, implementation details of the super class often "leak through" to the subclass, which is a big pain in the #$& for framework builders.
Apple chose to use delegation in many instances to address these problems; non-trivial classes like UIApplication expose common extension points through a delegate object so most developers have both an easier learning curve and a more loosely coupled way to add application specific behavior -- extending UIApplication directly is rarely necessary.
In your case, for your application specific code, use which ever techniques you're comfortable with and work best for your design. Inheritance is a great tool when used appropriately.
I frequently see application programmers draw lessons from framework designs and trying to apply them to their application code (this is common in Java, C++ and Python worlds as well as Objective-C). While it's good to think about and understand the choices framework designers made, those lessons don't always apply to application code.
In general you should avoid subclassing API classes if there exist delegates, etc that accomplish what you want to do. In your own code subclassing is often nicer, but it really does depend on your goals, eg. if you're providing an API you should provide a delegate based API rather than assuming subclassing.
When dealing with APIs subclassing has more potential bugs -- eg. if any class in the class hierarchy gets a new method that has the same name as your addition you make break stuff. And also, if you're providing a useful/helper type function there's a chance that in the future something similar will be added to the actual class you were subclassing, and that might be more efficient, etc but your override will hide it.
Please read the Apple documentation "Adding behavior to a Cocoa program"!. Under "Inheriting from a Cocoa class" section, see the 2nd paragraph. Apple clearly mentions that Subclassing is the primary way of adding application specific behavior to the framework (please note, FRAMEWORK).
MVC pattern does not completely disallow the use of subclasses or subtypes. Atleast I have not seen this recommendation from either Apple or others (if I have missed please feel free to point me to the right source of information about this). If you are subclassing api classes only within your application, please go ahead, no one's stopping you but do take care that it does not break the behavior of the class/api as a whole. Subclassing is great way of extending the framework api's functionality. We see a lot of subclassing within the Apple IOS framework APIs too.
As a developer one has to take care the implementation is well documented and not duplicated accidentally by another developer. Its another ball game altogether if your application is a set of API classes that you plan to distribute as reusable component.
IMHO, rather than asking around what the best practice is, first read the related documentation thoroughly, implement and test it. Make your own judgement. You know best about what you're up to.
It's easy for others (like me and so many others) to just read stuff from different sources on the Net and throw around terms. Be your own judge, it has worked for me so far.
I really think it depends on what you're trying to do. If the puzzle game you describe in the example really does have a set of unique elements that share common attributes, and there's no provided classes - say, for example, "NSPuzzlePiece" - that fit your needs, then I don't see a problem with subclassing extensively.
In my experience, delegates, data source methods, and informal protocols are much more useful when Apple has provided a class that already does something close to what you want it to do.
For example, say you're building an app that uses a table. There is (and I speak here of the iPhone SDK, since that's where I have experience) a class UITableView that does all the little niceties of creating a table for interaction with the user, and it's much more efficient to define a data source for an instance of UITableView than it is to completely subclass UITableView and redefine or extend its methods to customize its behavior.
Similar concepts go for delegates and protocols. If you can fit your ideas into Apple's classes, then it's usually easier (and will work more smoothly) to do so and use data source, delegates, and protocols than it is to create your own subclasses. It helps you avoid extra work and wasting time, and is usually less error-prone. Apple's classes have taken care of the business of making functions efficient and debugging; the more you can work with them, the fewer mistakes your program will have in the long run.
my impression of ADC's emphasis 'against' subclassing has more to do with the legacy of how the operating system has evolved... back in the day (Mac Classic aka os9) when c++ was the primary interface to most of the mac toolbox, subclassing was the de-facto standard in order for a programmer to modify the behaviour of commonplace OS features (and this was indeed sometimes a pain in the neck and meant that one had to be very careful that any and all modifications behaved predictably and didn't break any standard behaviour).
this being said, MY IMPRESSION of ADC's emphasis against subclassing is not putting forth a case for designing an application's class hierarchy without inheritance, BUT INSTEAD to point out that in the new way of doing things (ie OSX) there are in most cases more appropriate means to go about customizing standard behavior without needing to subclass.
So, by all means, design your puzzle program's architecture as robustly as you can, leveraging inheritance as you see fit!
looking forward to seeing your cool new puzzle application!
|K<
Apple indeed appears to passively discourage subclassing with Objective-C.
It is an axiom of OOP design to Favor composition over implementation.