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 tends to lead to unnecessary conflict.
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, it's heavily critized by experts and largely not true.
In any way, we know that this is a thing and is something that we need to deal with as part of our human experience. We've all been there, and I did it too back when I thought I had all the answers to the coding universe.
But 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 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.
I believe that part of the process of becoming an experienced software engineer is learning not to classify things in that "us vs them" way, and realizing that software engineering is complicated and most of the time even subjective.
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.
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.
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 developer'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.