4. Vodafone Proprietary classified as C2 - Internal
1 November 20194
• Now, after working for a few years in this area, cooperating with many excellent
engineers, I realized that the product design doesn’t really make the code so
complex. It’s me who makes it so complicated.
• We have the experience writing spaghetti code which significantly hurts the
performance of our projects. The question is how can we fix it?
A good architecture pattern might help.
5. Vodafone Proprietary classified as C2 - Internal
1 November 20195
• The term “good architecture” may sound way too abstract. It’s also difficult to know
where to start. Here’s a tip:
Instead of focusing on the definition of the architecture, we can focus on how to
improve the testability of the code
6. Vodafone Proprietary classified as C2 - Internal
1 November 20196
• We might not be able to master all of different types of architectures. However, we
are still able to keep a simple rule in mind:
no matter what architecture we decide to use, the ultimate goal is to
make test simpler
7. Vodafone Proprietary classified as C2 - Internal
1 November 20197
• Using “Make test simpler” approach helps us to:
– Start thinking before writing code
– Put emphasis on how to separate responsibility intuitively
– have a clear and reasonable mindset toward the design of the architecture.
– not stuck in trivial details anymore.
8. Vodafone Proprietary classified as C2 - Internal
1 November 20198
• I’ll talk about:
– The reason we choose the MVVM over the Apple MVC
– How to adapt MVVM to design a clearer architecture
– How to write a simple real-world app based on the MVVM
• I won’t talk about::
– The comparison between MVVM, and other architecture
– A silver bullet that will solve all problems
9. Vodafone Proprietary classified as C2 - Internal
1 November 20199
• Model
– Responsible for the business logic of the application.
– Reading and writing data
– Persisting application state
– May even include tasks related to data management, such as networking and data validation.
MVC (Model-View-Controller)
10. Vodafone Proprietary classified as C2 - Internal
1 November 201910
• View
– Should have two important tasks:
– presenting data to the user
– handling user interaction
– A core principle of the MVC pattern is the view layer's ignorance with respect to the model layer.
– Views are dumb objects.
– They only know how to present data to the user.
– They don't know or understand what they are presenting.
MVC (Model-View-Controller)
11. Vodafone Proprietary classified as C2 - Internal
1 November 201911
• Controller
– The view and model layers are glued together by one viewContoller.
– A controller knows about the view layer as well as the model layer.
– This often results in tight coupling, making controllers the least reusable component of an application based on the
MVC pattern.
MVC (Model-View-Controller)
12. Vodafone Proprietary classified as C2 - Internal
MVC Advantages
1 November 201912
• Separation of concerns
– In most applications, there is no confusion about what belongs in the view and model layer.
– What goes into controllers is often less clear.
– The result is that controllers are frequently used for everything that doesn't clearly belong in the view or
model layer.
• Reusability
– Whereas controllers are often not reusable, view and model objects are easy to reuse.
13. Vodafone Proprietary classified as C2 - Internal
MVC Problems
1 November 201913
• A clear separation of concerns is great.
– It makes our life as a developers easier.
– Projects are easier to architect and structure.
But that is only part of the story.
• If the code we write doesn't belong in the view or model layer. No problem. Dump it
in the controller. Problem solved. Right?
Not really.
14. Vodafone Proprietary classified as C2 - Internal
MVC Problem Example
1 November 201914
• Data formatting is a common task.
– Imagine that you are developing an invoicing application.
– Each invoice has a creation date.
– Depending on the locale of the user, the date of an invoice needs to be formatted differently.
• The creation date of an invoice is stored in the model layer and the view displays
the formatted date. That is obvious. But who is responsible for formatting the date?
– Remember that the view shouldn't need to understand what it is presenting to the user.
– But why should the model be responsible for a task that is related to the user interface?
15. Vodafone Proprietary classified as C2 - Internal
MVC Problem Example
1 November 201915
• Wait a minute.
– What about our good old controller?
– That’s why we called it a Massive View Controller.
MVVM is here to rescue
16. Vodafone Proprietary classified as C2 - Internal
1 November 201916
MVVM is proposed by John Gossman in 2005.
The main purpose of the MVVM is to move the
data state from the View to the ViewModel.
17. Vodafone Proprietary classified as C2 - Internal
MVVM (Model — View — ViewModel)
1 November 201917
• View
– According to the definition, the View consists of only visual elements.
– In the View, we only do things like layout, animation, initializing UI components, etc.
• ViewModel
– There’s a special layer between the View and the Model called the ViewModel
– The ViewModel is the representation of the View.
– ViewModel provides a set of interfaces, each of which represents a UI component in the View.
18. Vodafone Proprietary classified as C2 - Internal
MVVM (Model — View — ViewModel)
1 November 201918
• Binding
– We use a technique called “binding” to connect UI components to ViewModel interfaces.
– So, in MVVM, we don’t touch the View directly, we deal with business logic in the ViewModel and thus
the View changes itself accordingly.
• We write presentational things such as converting Date to String in the ViewModel
instead of the View
Therefore, it becomes possible to write a simpler test for the presentational logic
without knowing the implementation of the View.
19. Vodafone Proprietary classified as C2 - Internal
1 November 201919
Let’s take a higher look at the figure below.
– In general, the ViewModel receives the user interaction from the View,
– fetches data from the Model,
– then process the data to a set of ready-to-display properties.
– The View updates itself after observing the change of the ViewModel.
That’s the whole story of the MVVM.
20. Vodafone Proprietary classified as C2 - Internal
20 1 November 2019
We are going to see a simple app, in which:
– The app fetches popular photos from 500px API and lists
photos in a UITableView.
– Each cell in the table view shows a title, a description and the
created date of a photo.
– Users are not allowed to click photos which are not labeled
for_sale.
A simple gallery app — MVC
21. Vodafone Proprietary classified as C2 - Internal
1 November 201921
So what’s wrong with the code?
(The 4 problems)
A simple gallery app — MVC
22. Vodafone Proprietary classified as C2 - Internal
1 November 201922
• If you plan to write tests for the PhotoListViewController, we’ll find
ourselves stuck since it’s too complicated.
• We have to mock the APIService, mock the table view and mock the
cell to test the whole PhotoListViewController.
A simple gallery app — MVC
23. Vodafone Proprietary classified as C2 - Internal
1 November 201923
Remember that we want to make writing tests easier?
.
.
.
Let’s try MVVM approach!
24. Vodafone Proprietary classified as C2 - Internal
1 November 201924
• In order to solve the problem, our first priority is to clean up the view controller
• Split the view controller into two parts: the View and the ViewModel.
• To be specific, we are going to:
– Design a set of interfaces for binding.
– Move the presentational logic and controller logic to the ViewModel.
VCs Comparing Time!
Try MVVM
25. Vodafone Proprietary classified as C2 - Internal
25 1 November 2019
• Let’s take a look at the UI components
in the View:
– Activity Indicator (loading/finish)
– TableView (show/hide)
– Cells (title, description, created date)
• Each UI component has a
corresponding
property in the ViewModel.
• We can say that what we will see in the
View should be the same as what
we see in the ViewModel.
27. Vodafone Proprietary classified as C2 - Internal
1 November 201927
• Practically, in the ViewModel an interface/property for binding looks like this:
• On the other hand, in the View, we assign a closure to the propChanged as a callback closure for value
updates.
28. Vodafone Proprietary classified as C2 - Internal
1 November 201928
Interfaces for binding in ViewModel
(cellViewModels, numberOfCells, state)
29. Vodafone Proprietary classified as C2 - Internal
1 November 201929
Bind the View with the ViewModel
(callback closures in initVM())
30. Vodafone Proprietary classified as C2 - Internal
30 1 November 2019
Data Flow
1. The PhotoListViewModel starts to
fetch data.
2. After the data fetched, we
create PhotoListCellViewModel obje
cts and update the cellViewModels.
3. The PhotoListViewController is
notified of the update and then
layouts cells using the
updated cellViewModels.
34. Vodafone Proprietary classified as C2 - Internal
1 November 201934
Recap
• Made a binding theme using the closure.
• Removed all controller logic from the View.
• Created a testable ViewModel.
“The secret to getting ahead is getting started.” — Mark Twain