Codementor Events

How I Learned To Apply Clean Architecture

Published Jun 29, 2018Last updated Dec 26, 2018
How I Learned To Apply Clean Architecture

About me

I am an iOS developer, product designer, entrepreneur. I focus on creating apps for positive social or individual impact.

iOS is the main technology I worked with, so far. I worked with two agencies early in my career. I later carried that knowledge and did some freelancing. Then I started an app development agency.

Why I wanted to learn Clean Architecture

I believe that almost every iOS developer can launch an app. You can take the graphic design your designer gives you, create a view controller for each screen, mash some business logic in there to make it all integrate with your data and you’re done. Launch!

That’s what I did with Timefly, a product that helped you read relevant news. I launched a product with some cool features in about one month.

I realized that it’s easy to launch a product. Any developer with some basic knowledge can do it. I certainly could, even early in my career, and I enjoyed the speed that I could achieve. That's good. That’s part of how we achieved our technological progress. People created tools that make programming easier.

Later, my client wanted to add a new feature. I said: “Great!” More amazing work to deliver. But wait. I needed to modify some of the code here, add some code in this view controller. It all needed to work well with the previous features as well. No problem. I made it work.

Later my client wanted to add another news data source. Hmm. I mashed that code together and realised that my classes are starting to get bigger and bigger. It was harder to read. I started to forget where I should look to make a change. I needed to run the app, set a breakpoints to take everything step by step and figure out what was happening.

Imagine that you are an electrician and you need to install some new system in the following wiring.
camille-villanueva-562062-unsplash (1).jpg

I then made some changes to my code, made everything work and sent another build. Then I got the feedback from my client and some other part of my app didn’t work as it did previously.

At that time I realized that, yes, anyone can launch an app easily. However, it’s not that easy to launch an app, over and over again, consistently, easily, with confidence that you won’t break the older parts of the code. I needed to organize my code. It took me another month to study, refactor and organize my code better. I still didn’t know what I was doing. That’s how I started to learn more about better architecture patterns.

How I approached learning Clean Architecture

It wasn’t a direct learning path. I started to read a lot about different techniques to simplify my view controllers.

First, I experimented with MVVM (Model-View-ViewModel). I started to separate the business logic and other logic from the view controller. I add observers to the view model and make the view react to any changes in the view model. It was a slightly better pattern than MVC, so I applied everywhere.

Then I tried the VIPER pattern. It is much better than MVC and MVVM, as you no longer classify your code into 3 categories. You have 5 categories now: View, Interactor, Presenter, Entity, and Routing. That’s great!

Then I found that Clean Architecture is even better. I read the article that Uncle Bob wrote about Clean Architecture about 5 times. It was still hard to understand. I was still making mistakes, as something always didn’t make sense.

It was a slow learning process for me.

Challenges I faced

At first, I didn’t quite realize the importance of defining very well the application’s Entities and Use Cases. It is incredibly important and you have to get this first process right. As a mobile developer and, especially, as a visual mobile developer, I used UI paradigms to drive my thinking. I still thought of Buttons, Image views, Table views, Gesture recognizers as the main characters of an app. So I planned everything with those details in mind. I was making a crucial mistake.

Entities are the most important components. The use cases are the second most important component as they define certain operations for those entities. Buttons, image views, scroll views, CoreData, they are all details.

Also, in my attempts to get the architecture right, I wanted to test my code automatically, using unit tests. However, I realized that I still wasn’t writing my code to be easy to test. I had to learn to do that better and better, until I achieved a good level of competence and satisfaction.

Key takeaways

I would assume that everyone wants long-term success, not just short-term success. The role of the developer includes a negotiation with the product owner about this. A Clean Architecture is incredibly important to have for an app that wants long-term success. That’s why I’m putting a bet that it’s best to create a Clean Architecture from the start for all apps.

It will save everyone a lot of energy, it makes the app extensible and easy to test. It gives a sense of relief for the developers, as they know exactly where to look when reading, changing, adding or deleting code. They do less debugging.

Tips and advice

This learning journey to create a better and better architecture is all worth it. I would recommend all developers to take it. But don’t do it like I did it. Start directly with learning Clean Architecture. Use Test Driven Development to force you to write better and better code.

Final thoughts and next steps

My next learning goal is to try as many tools as possible that would speed up app testing. This includes unit testing frameworks, UI testing. However, I will always be interested in improving the architecture and making it more and more efficient.

Discover and read more posts from Cornel Chitanu
get started
post commentsBe the first to share your opinion
Greg Bell
6 years ago

Hi Cornel. You say:

“it’s best to create a Clean Architecture from the start for all apps.”

What I’ve learnt is that, sure, it’s good to have some idea of where to put things in the beginning (e.g. business logic in the model, etc.), but the pros always refactor relentlessly to better and better architectures.

To me this means end-to-end tests (e2e) are critical so that you can make sure your app still does what it’s supposed to do after you’ve made big, internal changes. This part, though, isn’t emphasized in most of the media on this subject. Everybody says to have mostly fast unit tests, which most people interpret to mean class or method level tests, and few slow e2e tests.

But that means you can’t change your architecture without changing your tests. I’m experimenting with the idea that maybe a ‘unit’ can be a single feature, still leaving you free to change the architecture wildly underneath).

Cornel Chitanu
6 years ago

Of course, there’s always good discussions to have about what to test. If your entities or use cases change radically, of course, that will have a big impact on your tests and code. The “business” is changing.

But if the internal big change means switching from MySQL to NoSQL, or switching from a web UI to a React Native UI, that shouldn’t affect most of the application. It should affect only the data layer, respectively the UI layer. A Clean Architecture done right, makes sure it doesn’t happen. Actually, this architecture tells us that those are more likely to change, so that’s why it’s good to plan to separate them.

A Clean Architecture doesn’t necessarily mean E2E tests, though. You can choose what to test, although it’s best to strive for 100% coverage. When it’s not possible you can prioritize.

I should experiment with the idea you mentioned as well (a “unit” is a feature). Let me know, if you have any tips on that.

Thank you for the coment! 🤜🤛

Greg Bell
6 years ago

Have a look at Behat/Cucumber. Not sure if the concept exists for iOS, but it should.

It’s BDD, which is supposed to flow down to TDD unit tests at lower levels. But I’m a solo dev, so I have to get the most bang for my buck. So describing features in English, then having tests for them, means I can muck around with lots of levels of my application, and still be sure that the feature does what it’s supposed to.

I think that makes them acceptance tests. But there’s one per feature, so in a way they’re unit tests. I’m probably butchering several concepts at once, but it’s worked pretty well for me so far.

Show more replies