There is no right or wrong in software engineering

There is no right or wrong in software engineering

Have you ever seen "preachings" like these in the wild west of Twitter, Medium, and LinkedIn?

  • "If you're not using X in 2023 you're an idiot!"
  • "XYZ architecture is the only way to go!"
  • "Doing X in Swift? Stop immediately!"

Humans' obsession with dividing things into groups is not unknown to psychology. The ability to quickly classify information is a core contributor to humanity's evolution and is something we start doing as soon as we're born.

But we need to be careful with the fact that sometimes this classification "feature" goes wrong. Instead of categorizing something as "this or that", we sometimes go for something more in terms of "us vs them", which not only leads to a lot of unnecessary conflict, but is also bad for our lives in general.

As far as I understand, the exact reason why humans do this is not fully understood. You might have heard of the "tribalism" theory which defines that humans are hardcoded to divide themselves in this "us vs them" fashion; this is mentioned a lot in pop culture, but from my understanding, this theory is heavily critized by experts and should not be considered true. But explanations aside, we know that this happens and is something everyone needs to understand and overcome at one point.

When it comes to software engineering, the reality is most things cannot be cleanly divided into "right or wrong" boxes like that. Yes, some things are concrete and indisputable. If an OS-level API states that you should never call it outside of the main thread, then that's what you should follow.

But most things are the opposite of that. When we talk about general problems and best practices, it's extremely rare for them to have a clear right or wrong way to go. Instead, they depend on what you're trying to achieve, and everyone is trying to achieve something different. There is no right or wrong in these situations, only different approaches.

To add another layer to the problem, a lot of stuff is also largely subjective! Many of our daily choices boil down to personal preference, making it even more senseless to attempt to categorize such things into clean "right" or "wrong" boxes. The industry even has a saying for this: there are no solutions, only trade-offs.

One's ability to understand this concept is the greatest indicator of seniority in my personal opinion. It's so common for intermediate-level engineers to fail to understand the subjectivity of software engineering that I find that you can accurately gauge someone's experience level by simply observing how well they grasp this concept. Those who don't understand it overengineer things and tend to get bogged down on details that are either subjective or outright pointless, while those who do understand it keep things simple and display a much better ability to prioritize important work and ignore less important details.

In this article, I'd like to shine a light on some of the topics that iOS developers tend to be divided on as a way to help developers who still haven't cleared that hurdle understand that these topics are not as straightforward as we might tend to think. Overcoming this barrier is part of the process of becoming a more experienced software engineer, and is something almost everyone goes through in their careers, so it's not something to be anxious about. I also had a period where I thought I had all the answers to the coding universe!

Tool Wars (e.g SwiftUI vs UIKit, Hybrid vs Native, CLI vs GUI, programming languages)

When a new framework, tool, or programming language is released, it's not uncommon for developers to divide themselves into groups and argue about which one of them is "better", claiming that theirs is the only option and everything else is a mistake.

The problem with this line of thought is that it assumes that one tool was created to completely replace another, and while sometimes this may very well be the case, in most cases it's not.

As a developer, it's important to understand that different tools solve different problems. While there may be some overlap between them, they were likely designed with different use cases in mind.

The biggest example here as of writing is the SwiftUI vs UIKit discussion. Despite being largely different from each other, social media is full of content about how one is "better" than the other.

Yes, SwiftUI and UIKit are both frameworks for building UI, but they solve different problems. As covered in my earlier "Thoughts on SwiftUI vs UIKit" article, SwiftUI is amazing for simple projects but quickly becomes inferior to UIKit as the project grows in complexity. Neither of these frameworks is better than the other, they are simply different tools for different jobs.

Discussions about Hybrid vs Native development also fall into this category. Hybrid development has a bad reputation because it generally results in apps of very low quality, but it saves companies a lot of time and money. Most companies reject this trade-off as they determine that quality is more important than saving a few bucks, but that doesn't mean that nobody should do so. If you're starting a company but don't have a lot of time or money, hybrid development can be a good way to bootstrap your business. It's not fair to compare these two in a "better/worse" fashion because they don't target the same set of problems.

I find that one example of how things can be subjective in this context is how a developer uses git. There is a lot of discussion about whether you should use it via the CLI or as a dedicated GUI app, but there isn't much to be discussed here because this is something that entirely boils down to your personal preference. There are pros and cons to each approach, and you will know which one is the right one for you because you will feel that it better suits your set of preferences. Neither approach is universally right or wrong.

Best Practices Wars (e.g architecture, general advice)

Architecture is usually the first thing that an iOS developer fights about. Every year we get a new architecture with some fancy acronym, that architecture gets a bunch of loyal followers, and then the groups start arguing about which architecture has the coolest name and solves the biggest number of problems. The first thing you learn is that MVC is terrible and should be avoided at all costs.

One unfortunate consequence of these fights around architecture is that it leads developers to pick architectures that solve problems that they don't really have (and not solving the problems they actually have), which are guaranteed to make a project harder to maintain in the long run.

It's important to understand that there is no architecture that solves all problems. Just like in the tools example, different architectures are meant to solve different problems, and the right architecture for your project is the one that solves your particular set of problems. MVC for example, which developers love to hate for some reason, can be a great choice for simple projects!

Architecture is not something that you pick once and stick with forever, but rather something that you continuously adjust as your project evolves and you start having to deal with different sets of problems. I have been told that my talk about how Spotify's iOS app is architected is great at demonstrating this, so I'm mentioning it here in case you want to check it out!

The same applies to general programming advice that you find on the web. We have a lot of content creators in our community, and I find that most of them present their content in the following format: "here's a thing, here's how it works, and here's what you can do with it". This is what I also strive to do when writing content for this blog, and I like this format because it doesn't claim that something is the best way of achieving something, it's simply showing you one possible way and leaving for you to decide whether or not that's the right solution for you.

But every once in a while, the algorithm recommends me content that is more in line with "here's a thing, and here's why you should always use it and abandon everything else". It's not about learning something new, it's about saying that you're wrong about something. There's usually a spike of this type of content in the WWDC week when new APIs are released.

The problem with content like this is that most best practices are highly subjective. Even if the content is referring to a very specific problem, it's hardly the case that the problem in question has one single viable solution. As we've already mentioned a couple of times in this article, personal preference plays a major role in this type of stuff. Something very helpful to you might be terrible for someone else, so they cannot be classified in a universal "right or wrong" fashion.

Programming Fundamentals War (e.g LeetCode)

Another common discussion point for iOS developers is whether or not you should learn computer science theory as part of your career. This is usually brought up whenever a company that run old-school programming puzzles (LeetCode) as part of their interview processes is mentioned.

This topic however is complex enough that it deserves its own article, and convieniently enough, such an article already exists! You can find more information about this in my "How necessary are the programming fundamentals?" article, but as a quick summary, this is a very complicated topic that has no objective right or wrong.

Conclusion

I hope this was able to help you see that some things in software engineering are more complicated than they might seem at first glance. Realizing this is an important step in a software engineer's career, and while this article will certainly not stop those wars from popping up every once in a while, I do believe that as a community we can help others get through this phase faster.