2007-06-16

Cocoa, falling at the first hurdle?

I was REALLY looking forward to programming some apps on the Mac using Cocoa and objective-C.

I am reading "Cocoa programming for MAC OS X" by Aaron Hillegas. I had read as far as page 30 when I saw the following:

"Objective-C is a very simple language. It has no visibility specifiers: All methods are public; and all instance variables are protected. (Actually, there are instance specifiers for instance variables, but they are rarely used. The default is protected, and that works nicely.)"


WHAT?

Works nicely? I disagree! It is actually possible to make a class's method private by not including it in the interface declaration (myclass.h) and just adding the implementation file instead, but what about protected methods?

public
I expose as little as needed to ensure the class provides the service it was designed to. The signatures/names of members in my public area change as little as possible so as not to break other people's code. Public members are therefore inflexible.

protected
I am happy to expose a few more methods here. Typically virtual methods so that anyone inheriting from my class can hook in their own code and modify the behaviour of my class. Protected members are a little more flexible to change as fewer lines of code depend on them, but I still try to change them as little as possible.

internal / friend
These are vital to me. They allow me (and only me) access to certain members of other classes. I find this invaluable when I need to have some kind of collaboration between classes in a framework that nobody else should have access to, including descendants of my own classes that are not in the same assembly/module.

private
An absolute necessity. Access to some members would allow a consumer to manipulate members of your class without obeying "the rules". This would include adding items to a private array member without going through the relevant method which might perform other tasks such as


  1. Enforcing read-only.

  2. Checking security permissions.

  3. Executing other methods to enforce proper business procedure.



As you can see, I feel very strongly about encapsulation. It provides flexibility to change the way you provide your service and enforces correct behaviour. When you order new computer from a manufacturer you don't walk along the conveyor belt interfering with the way each element is added do you? You interface with the manufacturer using the approved process (public PlaceOrder) and then leave them to get on with the 100 or so private procedures they go through to fulfill the order.

Never before have I read so little about a language before deciding it is a waste of time proceeding! Maybe encapsulation will be implemented along with the new garbage collection features (I wont go into reference counting) that is coming in the next version of Mac OS X. I'll have to wait and see!

6 comments:

Anonymous said...

(disclaimer: I'm not an Obj C'er or even die hard Mac)

To be honest I always have been a bit surprised by the fanatism of people in relation to information hiding.

People seem to consider it a purpose in itself, instead of a means to reach a goal.

Basically there are two possible roles in information hiding:

The role of the normal programmer: avoid stupid mistakes. This role needs a basic private/public, the rest is IMHO redundant and way overrated.

Some people also see a separate role for the component builder, usually with as much control as possible, to make sure the component is used in the way they envision.

That is IMHO also the problem with that view, nobody can imagine all possible uses and ways to extend a component, in all situations.

THerefore you see codebase after codebase that uses all kinds of dirty hacks to get at private fields, change visibility etc, leading to more obfuscation then simply doing away with it.

So in short, maybe it is a good thing.

Peter Morris said...

I disagree.

If I order a car from a manufacturer their interface to me asks a few things such as "What size engine?" etc. I do not need to know about the thousands of internal processes etc. (They could be made private.)

Within that company they most likely have variations of those processes (make those protected.)

The problem is that there is no such thing as protected in objective-C. So those would have to be made public. Don't you think that over complicates the interface that the consumer of my class has to work with? It also exposes methods that should be called only in specific circumstances.

What you seem to be describing is abuse of encapsulation which then requires hacking. You can abuse any technology. Preventing sensible users from doing something just because someone else abuses it is not a good thing.

Anonymous said...

I used Obj C for a brief stint years ago; that said, I've forgotten a lot of its details.

However, one thing I remember throughout using it: it is very much different from "normal" C-based OO languages and its solutions to common goals or problems are different. Specifically: protocols, categories, delegates, clusters etc.

I'd suggest reading the rest of the book before you pass judgement. :-) There may be different ways to accomplish what you're looking for.

UltraCrepidarian said...

Visibility specifications are syntactic sugar, and can be overcome, in Delphi.

You are using a broken system already. Right? Delphi.

Visibility specifications are moot.

What would you say to somebody who said, "Fine I won't use Delphi", and then proceeded to use Visual Basic instead.

You'd say, "You're an idiot", and you'd be right.

Right now, You're being an idiot.

Give Objective-C a chance. I am a delphi bigot and I know how you feel. But it's stupid to drop the whole thing on that basis.

Warren

UltraCrepidarian said...

Sorry, I meant to say, that "within a delphi unit, you can access private symbols between classes". That's not private, and thus Delphi is broken, but those of us who are used to it, are used to it. That's what I was trying to say. But my fingers couldn't keep up with my brain. I'm an idiot too. So there.

W

Peter Morris said...

Private in Delphi works more like "internal" where classes in the same unit can access it.

Actually I wrote most of my code in C# these days, and private works fine there. Sure you can get a method using Reflection, but that could hardly be done accidentally.

My gripe with objective-c is that it would appear to be very easy to accidentally execute "private" methods because there is no way of knowing it is private. With proper encapsulation I can make my class appear to be much more simple to the consumer by only exposing one or two methods and then having the other 200 methods private.