2

In Clean code it's suggested that private helper functions should always exist directly below the function they're directly used within. Should I be doing this when using computed properties? It's the norm to place private instance variables at the top of a class but in the case of what is essentially a helper function I find it confusing to do so.

The convention to keep our instance variables at the top of the class and our helper functions at the bottom are at conflict here. Should I be making this a function for the sake of convention? Keeping this where it is or putting it at the top of the class?

/// Done button in nav bar should let know that tapping will dismiss the view
func applyVoiceOverToNavigationBar() {
    guard timelinesAreInitialized else { return }
    let openDay = Scheduler.sharedInstance.timelines[SharedGlobals.Calendar.SELECTED_DAY].DAY.dayName
    self.navigationItem.rightBarButtonItem?.applyVoiceOverAccessibility(
        label: self.navigationItem.rightBarButtonItem?.title ?? "",
        hint:"VoiceOver.OpenScreenHint".localized.replacingOccurrences(of: "{Screen}", with: openDay))
}

private var timelinesAreInitialized: Bool {
    return Scheduler.sharedInstance.timelines.count > SharedGlobals.Calendar.SELECTED_DAY
}
4
  • 1
    The reason Clean Code says to do that is because it's easier to find the helper function from the function calling it. But what if two functions use the helper function? Three? Like all good rules, this one has exceptions. Like all good rules, it's meant to be followed only when it makes sense to follow it. Apr 10, 2018 at 15:30
  • 1
    Keep in mind that Clean code was probably not written with the understand that Swift can split classes between extensions, even between files. Typically, my main class body (for big enough classes) only contains instances members and initializes. Everything else is in extensions. This circumvents the problem that Clean code's approach is intended to solve.
    – Alexander
    Apr 24, 2018 at 18:54
  • @Alexander Do you put your computed properties in the main body with the stored instance variables or with the function(s) that utilize them? I can see it making sense when it's use is as a genuine cohesive instance variable but in the case above it is more of a private helper function only ever used by one class. Apr 25, 2018 at 8:02
  • 1
    @Deco it depends. As a hard and fast rule, I try to avoid hard and fast rule. They obscure your ability to use best judgement on a case-by-case basis. If a computed property is used to satisfy a conformance to a protocol, then I would put it in the extension that defines that type's protocol conformance. If it is very tightly coupled to a particular method, I would put it wherever that method was. And if it was some very frequently used convenience property, I might put it up in the main type declaration.
    – Alexander
    Apr 25, 2018 at 16:08

2 Answers 2

2

Should I be doing this when using computed properties? It's the norm to place private instance variables at the top of a class but in the case of what is essentially a helper function I find it confusing to do so.

Computed or not, it's very nice to not run into details first. Tell me the high level story first.

The surest way to undermine my argument is to use crappy names. I didn't mind reading timelinesAreInitialized before it had been defined. Why? Because it's name made your intent very clear.

I understand this goes against convention in many languages and any code base should be consistent but all other things being equal this is the better style.

Having a convention is good for consistency. But this means you can't follow the best wisdom of today because you've enshrined the best wisdom of the past. When presented the opportunity to make a clean break don't repeat the mistakes of the past.

0

It's the norm to place private instance variables at the top of a class

I once experimented with not doing this as it seems a nonsense convention to me. I'm with CandiedOrange here, put the bigger picture at the top and the details at the bottom. But, for C# at least, the compiler got really confused all too easily as I edited the file, meaning it often lost sight of those fields and reported errors on lots of lines.

So I now stick to that convention for pragmatic reasons. Everything else private gets shoved to the bottom where it belongs though: properties, inner types, methods etc. And I really mean the bottom: all private members come after all public ones.

1
  • 1
    That's a major annoyance in Swift: If you edit something in the middle of your source file, and your brackets are not exactly matching, then it loses track of functions behind your edit and suddenly gives you gazillions of errors. I suppose C# does the same. So that would make you adopt a coding style where you usually edit code at the end of the file only :-(
    – gnasher729
    Apr 11, 2018 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.