An unpopular opinion about code style

In the realm of code style, there is a rule that I navigate against the mainstreams accepted behaviour.

More often than not, code style will encourage against having long file and function body length. This is good practice! The longer a file or function is, the more likely that readiness and maintainability will be poor.

If we take swiftlint as an example, they set a default rule like this:

| function_body_length                     | no     | no          | no                     | metrics     | no       | warning: 40, error: 100

This means a warning if a function does 40 lines and an error if more than 100 lines.

Which tends to lead a lot of developers to write setup functions within class initialisation like this.

class MainViewController: UIViewController {
	override func viewDidLoad() {
		super.viewDidLoad()
		
		setupViews()
		setupAutoLayout()
		setupBinding()
	}
	
	private func setupViews() {
		// Add subviews
	}
	
	private func setupAutoLayout() {
		// Apply auto layout to views
	}
	
	private func setupBinding() {
		// Bind to view model
	}
}

And this practice, in the name of code clarity, will start being applied repeatedly in the codebase.

So, that might be a good practice, or it might not. What purpose does creating a setup function that you are going to only use once serve?

The answer is obvious - readability! Your initialisation function will be much shorter.

Yet, I would encourage you to think about the implications and butterfly effects created while extracting non reused code into a separate function:

  • It forces the reader to navigate (scroll) throughout the code to read the whole initialisation

  • It creates a false signal that the code extracted is indeed reusable, while it is likely it was not designed to be reused

  • If you change a view, you have to bring modification to several different functions that you might forget about

  • It doesn’t make your initial function better in any way as you now have multiple functions to take care of with each its inputs and outputs

I would rather encourage you to keep all your code in the same function, using a few comments to separate sections:

class MainViewController: UIViewController {
	override func viewDidLoad() {
		super.viewDidLoad()
		
		// Add subviews
		// Code to add subviews
		
		// Apply auto layout to views
		// Code to apply auto layout
		
		// Bind to view model
		// Code to bind the view model
	}
}

This brings several advantages:

  • You can read your code linearly and without interruption, giving you a better overview of what it does from end to end

  • You are sure your code will only be executed once

  • You reduce input and outputs as all elements are at the same place

If you find that your function is too large, ask yourself the good questions to find the best solutions. It is likely that what you need is to revise your architecture and design patterns to make your code lean and readable. Chunking your code into bits doesn’t magically make it more readable, it just spreads it, making small bits easier to read, but the big picture is harder to understand.