views:

58

answers:

4

In the book Clean Code the author recommends breaking large methods into small functions that do one specific thing. In languages like Java this translates to pretty, readable code.

public static String renderPage(PageData pageData)
{
    includeHeader(pageData);
    includeContent(pageData);
    includeFooter(pageData);
    return pageData.getHtml();
}

However in Objective-C as far as I know the only way to implement functions like this are to create private methods and call them by messaging self

- (NSString *)renderPageWithData:(PageData *)pageData {
    [self includeHeader:pageData];
    [self includeContent:pageData];
    [self includeFooter:pageData];
    return [pageData HTML];
}

I feel like messaging self implies some sort of operation that the object is doing to itself. C functions aren't really an option because the don't fall under the scope of the class. Meaning I can't access any of the instance variables or the class object with out doing extra legwork, and adding complexity.

I'm looking for a good way to create clean code with regard to functions or methods in Objective-C

+1  A: 

I'm not sure what you mean by "they don't fall under the scope of the class"; local C functions that don't need to get at object member properties seem like a fine solution here to me. But I don't think there's anything particularly wrong with private methods, either.

Personally, I would use C functions here.

Edit: if your refactored functions need access to object state—implying that you'd be passing self as an argument—then I'd go ahead and leave it as a method. There's very little difference between

[self includeHeader:pageData];

and

includeHeader(self, pageData);

Even if you find both of these options slightly distasteful from an aesthetic position, they're both huge improvements for readability and its close cousin, maintainability, compared to having long functions that do several different pieces of work.

Seamus Campbell
Thats the problem I would often be generating functions that need access to member properties. It seems like unjustified complexity to handle messaging references to self. But maybe its the only options.
rebelzach
+2  A: 

There is no difference between the two code blocks you posted. The only reason it looks different is that in java, the this. is implicit when you make a function call without specifying an object.

Edit: I just noticed that your java method is static. If you want them to remain static methods, you would then just use [MyCLass ...] instead of [self ...].

unholysampler
It seems many people have an issue with this, it's just semantics ;)
KevinDTimm
Your right I shouldn't have the `static` in there. I will probably go with using private methods that operate on member properties directly. I guess I just have to get over my `self` messaging issues.
rebelzach
A: 

You should be using class methods when they share some properties.

Without to see all the code, and without to know how the code is used, I could suggest to create a pageData property, and change the other functions so they don't need to pass the parameter between them. If it is not possible, or the parameter pageData is very temporary, then plain functions could be better.

kiamlaluno
+1  A: 

I see your point about the function calls: self and include in the same "sentence" make it look as though things are being included in the class itself. I would solve that with more explicit method names:

- (NSString *)renderPageWithData:(PageData *)pageData {
    [self renderHeaderWithData:pageData];
    [self renderContentWithData:pageData];
    [self renderFooterWithData:pageData];
    return [pageData HTML];
}
e.James
Thanks for this. Making it more like a sentence certainly helps clean it up.
rebelzach
No worries. As for the use of `[self ...`, that's just something you have to get used to `:)`. By the time you've written a couple of hundred function calls, you don't even notice it any more.
e.James