Re: object type testing
Re: object type testing
- Subject: Re: object type testing
- From: Erik Buck <email@hidden>
- Date: Sun, 7 May 2006 18:07:34 -0400
Others have said it or implied it before in this thread, but it is
worth repeating. Needing to know the specific class of an object
almost always implies a serious design flaw. THis is not just a
Cocoa truism; it applies to ALL object oriented languages that
implement inheritance and/or polymorphism.
A key element of object oriented programming is polymorphism. Any
attempt to restrict or even check the specific class of an object is
a direct attempt to defeat polymorphism. Furthermore, there are
certain essential characteristics of objects. One essential
characteristic is that any instance of a class is substitutable for
any instance of that class and all super-classes. Any attempt to
evade the substitutability principal will 1) confound all future
users of the class and 2) make it virtually impossible to use the
class with any pre-existing framework.
I don't mean to pick on anyone in particular, but let's examine this
code:
- (IBAction)doGroupsChecks:(id)sender {
if ([sender isMemberOfClass:[NSMatrix class]]) {
// find out which button was hit by calling [onButton
tag] and do
appropriate stuff
...
}
if ([sender isMemberOfClass:[NSButton class]]) {
// do stuff to keep track of which check box was hit
...
}
}
There are many things I would do differently. First, I assume from
the comment that the tag of a cell is being used to make some
decision. If that correlates to using a C switch statement or even
looking up object values in a table based on tag, that is IMHO a bad
design. [Just like needing to know the class of an object signals
bad design, any use of C switch statements signals a bad design given
that polymorphism is a better alternative almost every time.]
How about this code written in main:
- (IBAction)groupWasSelected:(id)sender
{
id representedObject = nil;
if([sender respondsToSelector:@selector(selectedCell)])
{
representedObject = [[sender selectedCell] representedObject];
}
else if([sender respondsToSelector:@selector(representedObject)])
{
representedObject = [sender representedObject];
}
[representedObject doSomething] // Use polymorphism to do the
right thing
}
In the code above, polymorphism can be used to do the right thing.
It doesn't matter what the class of sender is as long as sender has
either a selected cell or can return a represented object directly.
This code is very flexible. You can change the user interface to use
custom objects, change from a matrix to a table, etc. without
breaking any code.
In summary, coupling is the enemy of object oriented programming.
Having to know the class of a user interface object couples code to
the class of the user interface object making it more difficult to
change the user interface object without breaking the code. Even the
use of tags introduces coupling because the significance of tags may
be lost on the poor fellow who changes the user interface later.
Tags are fragile because they are seldom documented anywhere and
someone who is just looking at the nib file will have no idea what
the significance of all those magic numbers is. [Use of magic
numbers is a likely sign of bad design.]
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden