Why App Architecture Matters

Written by: Reinder de Vries, November 28 2017, in App Development

Why App Architecture Matters

You wouldn’t build a house on quicksand. Would you build an app without architecture?

A while back I got an email from an iOS developer. He was tasked with extending an app with new features. The app was built by someone else.

He ran into these issues:

  • “When I change one thing in the code, another part breaks!”
  • “I can’t find any feature of the app. They are all over the place.”
  • “There is no uniform structure for this app, so how can I extend it?”

We emailed back and forth, and came to the conclusion that the app lacked architecture.

Once we had that sorted out, the developer started the tedious process of rebuilding most of the app. He refactored code, made uniform APIs and applied a thoughtful app architecture to the project.

In this article, we’ll discover what led to this conclusion. Why does app architecture matter?

  1. When Your App Breaks In Random Places
  2. Encapsulation, Abstraction, Documentation
  3. Pick Your App Architecture
  4. Why App Architecture Matters
  5. Further Reading

When Your App Breaks In Random Places

This joke always gets me. Do you know it?

99 little bugs in the code
99 little bugs in the code
Take one down, patch it around
127 little bugs in the code…

I like to think that the person who wrote this “poem” (by lack of a better word) wrote code without an architecture.

You have a bug. You fix it. You now have more bugs. Code breaking in random places. How?

Technically, apps consist of many smaller components put together. A database, user interfaces, a back-end, and app features like social sharing, user authentication – they are the components that make up an app.

Every one of those components has more smaller components. When you go one level deeper, a database has objects it saves, code to read and write, code to cache data, code to interpret database queries, and so on.

Every one of those components has more smaller components. The database caching mechanism has code to empty the cache, to add cached objects, to remove them, and code to keep an eye on available memory.

And so on. Components on top of components on top of components, comprising an entire system. This system is the app.

At this point, there aren’t any problems yet. You can very well build an app that uses all these components. Most of the time, you’re only working directly with the high-level components of an app anyway!

Where does it go wrong?

Let’s say you’re building an app that has a list of movies. Your app saves Movie objects in the database. Movies have properties: a title, a director, a cast, and so on.

At one point you decide to add TV shows to your app. Because movies and TV shows are so much alike, you decide to use the Movie objects to save TV shows.

You use a function called isShow() to indicate a TV show. It returns true when the movie object is a TV show.

This works OK for some time. After a year a new developer comes along to work on this app. He decides to add a new property to TV shows called episode. He adjusts the isShow() function to only return true when the episode property contains a value.

Suddenly, the entire database breaks. Objects that are TV shows show up as movies, and objects that are movies don’t show up at all…

Get 5 of my best practices

Get 5 of my best practices

Learn how to build better iOS apps

I’ll show you exactly how I built a dozen professional iOS apps,
write extensible Swift code, and turn coffee into code.
Wait, what? Yup – into Swift code.

Encapsulation, Abstraction, Documentation

What caused this bug?

Both developers relied on the isShow() function to work correctly. Code that depended on the function broke, because its implementation changed.

You could argue that properly documenting the dependencies of the isShow() function would have prevented this bug. In hindsight, that seems a reasonable solution.

When building systems, we usually only look in the rearview mirror when things break. So how do you look into the future, avoiding this bug before it even happens?

A good app architecture is based on 3 ideas:

  • Encapsulation: clearly defining the boundaries of a component.
  • Abstraction: hiding complexity from the developer.
  • Documentation: communicating expected input and resulting output.

Encapsulation means that you clearly define the boundaries of a component. You make a “capsule” of your code. You can only use the component via formal functions that encapsulate data, like setTitle(_:) or isMovie().

The complex logic inside the movie objected is abstracted away or “hidden”. You or another developer don’t have direct access to the object’s data. You can’t change its implementation after it has been finalized.

Abstraction is crucial in software development. With it, you can avoid exposing too much complexity to a developer (or yourself).

This is an advantage. When the “capsule” is finished, you don’t have to worry about its implementation any more. With unit testing you can test the integrity of the capsule and keep it compatible with the rest of your code.

Properly documenting your code means adding code comments where necessary. You add so-called “Docblocks” to functions, properties and classes. They describe purpose of a component, the expected input, and the resulting output.

It’s common to also describe other aspects of an app codebase, like how to get it up and running, where to find usernames and passwords, and what open source libraries the project depends on.

It’s important to note here that architectural patterns like MVC, MVVM and VIPER are valuable because they define relationships between components of your app. On a fundamental level they still use the principles of encapsulation and abstraction, among many others.

Good code clearly defines boundaries of a component, hides complexity from the developer, and communicates expected input and resulting output.Click To Tweet

Pick Your App Architecture

App architecture is in constant flux. For instance, the VIPER app architecture recently rose in popularity among iOS developers.

Model-View-Controller (MVC) has often been scorned by the community. It’s very easy to create massive classes of code with MVC, if you don’t follow certain guidelines.

Ironically, the principles of MVC lie at the foundation of so many other architectural patterns. In defense of MVC: don’t judge the architecture for the mistakes of the developer.

As a developer it’s important to master app architecture, design patterns and software engineering principles to a certain degree.

When you grasp the foundations that underlie many of these architectures, it’s much easier to pick up a novel architectures like VIPER. It often doesn’t work the other way around.

As an iOS developer you can choose from a wide range of architectures, design patterns and engineering principles. It’s too complex to go into all of them at this point. Make your pick!

Software development principles:

Architectural patterns:

Design patterns

  • Decoration
  • Builder and Factory
  • Singleton
  • Appearance
  • Iterator
  • Observer-Observable
  • Delegation
  • Coordinator

Programming paradigms:

Build better iOS apps by mastering best practices and app architecture » Find out how

Why App Architecture Matters

Back to the apps we’re working on. The following issues are the kinds we run into as iOS developers.

  • “When I change one thing in the code, another part breaks!”
  • “I can’t find any feature of the app. They are all over the place.”
  • “There is no uniform structure for this app, so how can I extend it?”

Creating an app with the right architecture solves these problems. Your app’s architecture gives its components structure and formalizes how they talk with each other.

As a result you get an app that …

  • … doesn’t easily break, has fewer bugs, and is easy to maintain.
  • … has a codebase that’s easy to understand and navigate.
  • … has reusable code and can be extended with new features.

You could say that we, as iOS developers, have created rules that we all follow and understand. When you take on a project that someone else built, or continue on your own projects, you can rely on the integrity of the work because of these rules.

By the way, it’s never too late to architect your app. You want to do it sooner than later, of course.

When you refactor your code you essentially rewrite the code that doesn’t follow your architectural design anymore. Making this your practice is essential!

Ultimately, you spend less time fixing bugs, more time building great apps, which means happy customers, happy employer, and that means a happy you.

Get 5 of my best practices

Get 5 of my best practices

Learn how to build better iOS apps

I’ll show you exactly how I built a dozen professional iOS apps,
write extensible Swift code, and turn coffee into code.
Wait, what? Yup – into Swift code.

Further Reading

Now you know! The architecture of your app matters. It’s good that you care.

You wouldn’t build a house on quicksand. You wouldn’t build an app without putting some thought into its architectural design.

Want to learn more? Check out these resources:

Enjoyed this article? Please share it!

You get into trouble when the connections between components of your app aren’t formally structured. App architecture solves this problem.Click To Tweet

Reinder de Vries

Reinder de Vries is a professional iOS developer. He teaches app developers how to build their own apps at LearnAppMaking.com. Since 2009 he has developed a few dozen apps for iOS, worked for global brands and lead development at several startups. When he’s not coding, he enjoys strong espresso and traveling.

Comments & Questions

Got a comment or question? Let me know! I read and respond to every one. Thanks!