Re: Objective-C++, class scope constants, name conflicts
Re: Objective-C++, class scope constants, name conflicts
- Subject: Re: Objective-C++, class scope constants, name conflicts
- From: Erik Buck <email@hidden>
- Date: Fri, 10 Feb 2006 19:24:16 -0500
I perceive that there is a very fundamental difference in object
oriented philosophy being exposed by this exchange.
Scott Ribe seems to be saying that he wants a constant defined with
class scope declared in the interface of a class. This is not
supported by Objective-C. The specific reason he wants this constant
in the interface as opposed to the implementation is that he wants to
allocate storage for a C array containing exactly that constant
number of pointers to Objective-C objects.
Mr. Ribe states that he thinks a lack of this feature (class scope
constant declared in class interface) in Objective-C "seems an odd
omission."
The difference in object oriented philosophy is revealed by the fact
that I don't think it is an odd omission. This is why...
The specific number of instances referenced by an object is IMHO an
implementation detail. Mr. Ribe states that the referenced objects
are in fact Cocoa controls in a user interface. This is certainly an
implementation detail that should never be exposed in a class
interface. Mr. Ribe seems to want maximum coupling between several
"things" that should be separately encapsulated: A nib file, a custom
class, and all the code that uses the class. Coupling is BAD and
should usually be minimized. The question that should always be
asked is the following: If I change X, will I also have to change Y
in order to preserve a working system ? If the answer is yes, a
basic goal of object oriented design has not been achieved.
Mr. Ribe insists that there are exactly six controls in his user
interface, and he certainly knows his application domain better than
I do. Maybe there is no possibility that a seventh control will ever
be added or that five might be adequate. If there is any reasonable
possibility that the user interface could change, I would argue that
he automatically has a flawed design...but let's assume he is right.
The constant that Mr. Ribe wants to declare will be used to determine
how many pointers to objects will be stored in a C array. I question
the wisdom of using a C array for this purpose at all. By using a C
array, Mr. Ribe is creating extra work for himself and potentially
introducing memory errors. Cocoa collections retain the objects they
contain. C arrays do not. By not using an Cocoa collection (with
exactly six elements or not), Mr. Ribe takes on the _extra_ burden to
correctly manage the reference count of objects referenced by the
array. The _extra_ (but required) messages to retain will most
likely seem very odd to the poor programmer who has to maintain this
Cocoa convention flouting code that Mr. Ribe is writing.
The obvious other reason to declare the constant number of array
elements in the class interface is so that the following code can be
written (using C++ syntax):
SomeControlClass **arrayOfSomeClass =
someObjectThatHasArray.GetCArrayOfSomeClass();
for(i = 0; i < SomeClass::someConstant; i++)
{
SomeControlClass *currentControl = arrayOfSomeClass[i];
// Call some member functions of currentControl
}
I think the above code is an anti-pattern!
Here is a version I think is much better in Objective-C
NSEnumerator *objectEnumerator = [[someObjectThatHasCollection
collectionOfSomeClass] objectEnumerator];
id currentControl;
while(nil != (currentControl = [objectEnumerator nextObject]))
{
// send some messages to currentControl
}
I think this version is better for the following reasons:
1) The while loop does not depend on the number of objects stored in
the collection
2) The while loop does not depend on the type of collection used to
store objects
3) The stored objects don't have to be the same type (heterogeneous
collection)
4) The class of the object that provides the collection does not have
to be known to compile the while loop. Hard coding
SomeClass::someConstant means that the code is fragile and will break
if a subclass of SomeClass is ever introduced.
SomeClass::someConstant is not polymorphic! In the Objective-C
version, any object that responds to -collectionOfSomeClass can be
used with the while loop.
Note: Higher Order Messaging (HOM) could be used to eliminate even
the while loop in the Objective-C version making this a one line
example!
Note: As Mr. Ribe recognizes, he could have used std::vector<
BloodPressure_ControlGroup
* >. If he at least used std::vector, he could have used an STL
iterator and avoided the fragile non-polymorphic use of a magic
constant. However, unless he also uses an IMHO excessive amount of
wrapping of Objective-C instance pointers in "smart" C++ pointers and/
or other _extra_ code he will still have convention flouting
reference count issues.
Note: I am tempted to say that we are seeing a culture/philosophy
clash between a C++ programmer and the Cocoa/Objective-C language,
but that is not really true. C++ programmers have long recognized
that what Mr. Ribe wants to do is a poor solution in most cases.
References:
http://www.ddj.com/documents/s=917/ddj9808a/ "Separating concerns of
interface aspects and inherited implementation aspects is a good
practice. It keeps designs clean and fosters sensible paths of reuse."
http://www.octopull.demon.co.uk/c++/implementation_hiding.html
http://www.codeguru.com/cpp/cpp/cpp_mfc/oop/article.php/c9989/
_______________________________________________
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