├── .github
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── README.md
├── clean_architecture_cheatsheet.md
├── media_files
├── clean_architecture.jpg
├── clean_architecture_android.png
├── cleanish_android.png
├── cleanish_android.xml
├── configuration_change.png
├── configuration_change_simpler.png
├── ioc.jpg
├── ioc_inject.jpg
├── ioc_sl.jpg
├── model2_mvc.png
├── model2_mvc_sequence.png
├── mvc_jsp.png
├── mvc_mvp_mvvm.png
├── mvc_original.png
├── mvc_vs_mvp.png
├── mvp_android_diagram.png
├── mvp_passive_view.png
├── mvp_supervising_controller.png
├── mvvm.png
├── mvvm_viewmodel_scope.png
├── onion_architecture.png
├── presentation_patterns.png
└── save_restore_options.png
├── mvc_cheatsheet.md
├── mvp_cheatsheet.md
├── mvvm_cheatsheet.md
└── pattern_differences.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [jemshit]
4 | custom: ['https://etherscan.io/address/0x355781C0Bc3cdeFE26d7767EE36976ffE4bE9459', 'https://www.bscscan.com/address/0x355781C0Bc3cdeFE26d7767EE36976ffE4bE9459', 'https://www.blockchain.com/btc/address/bc1qa4lzsq8c2dqsnh9e5j7sw8cxryl8ca9as0j4ex', 'https://blockchair.com/litecoin/address/ltc1qzwwmdypzcje2aqpuk2vcz6h0kxs9ky7wewt27u', 'https://explorer.solana.com/address/BAJKDUY4zJUAFt3VWHjftxbMgFw15ZGxpdAi6kkYb7ts']
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by https://www.gitignore.io/api/linux,macos,windows
2 | .idea/
3 |
4 | ### Linux ###
5 | *~
6 |
7 | # temporary files which can be created if a process still has a handle open of a deleted file
8 | .fuse_hidden*
9 |
10 | # KDE directory preferences
11 | .directory
12 |
13 | # Linux trash folder which might appear on any partition or disk
14 | .Trash-*
15 |
16 | # .nfs files are created when an open file is removed but is still being accessed
17 | .nfs*
18 |
19 | ### macOS ###
20 | *.DS_Store
21 | .AppleDouble
22 | .LSOverride
23 |
24 | # Icon must end with two \r
25 | Icon
26 |
27 | # Thumbnails
28 | ._*
29 |
30 | # Files that might appear in the root of a volume
31 | .DocumentRevisions-V100
32 | .fseventsd
33 | .Spotlight-V100
34 | .TemporaryItems
35 | .Trashes
36 | .VolumeIcon.icns
37 | .com.apple.timemachine.donotpresent
38 |
39 | # Directories potentially created on remote AFP share
40 | .AppleDB
41 | .AppleDesktop
42 | Network Trash Folder
43 | Temporary Items
44 | .apdisk
45 |
46 | ### Windows ###
47 | # Windows thumbnail cache files
48 | Thumbs.db
49 | ehthumbs.db
50 | ehthumbs_vista.db
51 |
52 | # Folder config file
53 | Desktop.ini
54 |
55 | # Recycle Bin used on file shares
56 | $RECYCLE.BIN/
57 |
58 | # Windows Installer files
59 | *.cab
60 | *.msi
61 | *.msm
62 | *.msp
63 |
64 | # Windows shortcuts
65 | *.lnk
66 |
67 |
68 | # End of https://www.gitignore.io/api/linux,macos,windows
69 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Jemshit Iskenderov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### :blue_book: Android Architecture, Pattern Notes
2 | Derived from many blog posts, websites, online discussions and experiences. Even after writing a lot of applications, one may forget reasons of used techniques (why i did this, or what is benefit of this pattern...). Reason for this may be copy pasting some of your own code after writing once.
3 |
4 | This repo aims to be note to lookup for below topics. It can also be good reference when trying to explain these topics to colleagues.
5 |
6 | ## Architectures
7 | ### 1. [Clean Architecture notes](https://github.com/jemshit/android_architecture_notes/blob/master/clean_architecture_cheatsheet.md)
8 | General and Android specific
9 |
10 | ## Presentation Patterns (Delivery Mechanisms)
11 | ### 1. [MVC notes](https://github.com/jemshit/android_architecture_notes/blob/master/mvc_cheatsheet.md)
12 |
13 | This is MVC variants in general (not Android specific), so difference between these patterns can be seen.
14 |
15 | ### 2. [MVP notes](https://github.com/jemshit/android_architecture_notes/blob/master/mvp_cheatsheet.md)
16 | MVP in general and from Android perspective
17 |
18 | ### 3. [MVVM notes](https://github.com/jemshit/android_architecture_notes/blob/master/mvvm_cheatsheet.md)
19 | MVVM in general and from Android perspective
20 |
21 | ### 4. [Pattern Differences note](https://github.com/jemshit/android_architecture_notes/blob/master/pattern_differences.md)
22 | MVC vs MVP vs MVVM
23 |
--------------------------------------------------------------------------------
/clean_architecture_cheatsheet.md:
--------------------------------------------------------------------------------
1 | ## 1. Onion Architecture Overview
2 |
3 |

4 |
5 | Figure reference: [[4]](#6-references)
6 |
7 | - “The diagram to the left depicts the Onion Architecture. *The main premise is that it controls coupling*. **The fundamental rule is that all code can depend on layers more central, but code cannot depend on layers further out from the core. In other words, all coupling is toward the center.**" [[4]](#6-references)
8 |
9 | - "This architecture is unashamedly *biased toward object-oriented programming*, and it puts objects before all others. In the very center we see the **Domain Model**, *which represents the state and behavior combination that models truth for the organization*. Around the Domain Model are other layers with more behavior. The number of layers in the application core will vary, but remember that the Domain Model is the very center, and since all coupling is toward the center, *the Domain Model is only coupled to itself.*" [[4]](#6-references)
10 |
11 | - "The first layer around the Domain Model is typically **where we would find interfaces that provide object saving and retrieving behavior, called repository interfaces.** The object saving behavior is not in the application core, however, because it typically involves a database. *Only the interface is in the application core.*" [[4]](#6-references)
12 |
13 | - "Out on the edges we see **UI (presentation pattern), Infrastructure (web service, file, DB), and Tests.** *The outer layer is reserved for things that change often.* These things should be intentionally isolated from the application core. Out on the edge, we would find a class that implements a repository interface. This class is coupled to a particular method of data access, and that is why it resides outside the application core. This class implements the repository interface and is thereby coupled to it. The Onion Architecture relies heavily on the *Dependency Inversion principle*. The application core needs implementation of core interfaces, and if those implementing classes reside at the edges of the application, we need some mechanism for injecting that code at runtime so the application can do something useful. **The database is not the center. It is external…** Hexagonal architecture and Onion Architecture share the following premise: **Externalize infrastructure and write adapter code so that the infrastructure does not become tightly coupled.**” [[4]](#6-references)
14 |
15 | "Key tenets of Onion Architecture:
16 | - The application is built around an independent object model
17 | - Inner layers define interfaces. Outer layers implement interfaces
18 | - Direction of coupling is toward the center
19 | - All application core code can be compiled and run separate from infrastructure" [[4]](#6-references)
20 |
21 | ## 2. Terminology
22 |
23 | #### a) Inversion Of Control
24 |
25 | ##### Why is necessary?
26 |
27 | - "A common issue to deal with is *how to wire together different elements*: how do you fit together this web controller architecture with that database interface backing when they were built by different teams with little knowledge of each other. A number of frameworks have taken a stab at this problem, and several are branching out to provide a general capability to assemble components from different layers." [[9]](#6-references)
28 |
29 | - "I use component to mean a glob of software that's intended to be used, without change, by an application that is out of the control of the writers of the component. By 'without change' I mean that the using application doesn't change the source code of the components, although they may alter the component's behavior by extending it in ways allowed by the component writers. A service is similar to a component in that it's used by foreign applications. The main difference is that I expect a component to be used locally (think jar file, assembly, dll, or a source import). A service will be used remotely through some remote interface, either synchronous or asynchronous (eg web service, messaging system, RPC, or socket.) I mostly use service in this article, but much of the same logic can be applied to local components too. Indeed often you need some kind of local component framework to easily access a remote service." [[9]](#6-references)
30 |
31 | ```java
32 | class MovieLister{
33 | private MovieFinder finder;
34 |
35 | public MovieLister() {
36 | finder = new ColonDelimitedMovieFinder("movies1.txt");
37 | }
38 |
39 | public Movie[] moviesDirectedBy(String arg) {
40 | List allMovies = finder.findAll();
41 | for (Iterator it = allMovies.iterator(); it.hasNext();) {
42 | Movie movie = (Movie) it.next();
43 | if (!movie.getDirector().equals(arg)) it.remove();
44 | }
45 | return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]);
46 | }
47 | }
48 |
49 | public interface MovieFinder {
50 | List findAll();
51 | }
52 |
53 | ```
54 |
55 | Code Reference: [[9]](#6-references)
56 |
57 | 
58 |
59 | Figure reference: [[9]](#6-references)
60 |
61 | - “... The MovieLister class is dependent on both the MovieFinder interface and upon the implementation. We would prefer it if it were only dependent on the interface, but then how do we make an instance to work with?” [[9]](#6-references). Since 3rd party users may want to use their own implementation like a plugin [[10]](#6-references) so no code change is required in MovieLister.
62 |
63 | - "Expanding this into a real system, we might have dozens of such services and components. In each case we can abstract our use of these components by talking to them through an interface (and using an adapter if the component isn't designed with an interface in mind). But if we wish to deploy this system in different ways, we need to use plugins to handle the interaction with these services so we can use different implementations in different deployments. So the core problem is how do we assemble these plugins into an application? This is one of the main problems that this new breed of lightweight containers face, and universally they all do it using Inversion of Control." [[9]](#6-references)
64 |
65 | - "In my naive example the lister looked up the finder implementation by directly instantiating it. This stops the finder from being a plugin. The approach that these containers use is to ensure that any user of a plugin follows some convention that allows a separate assembler module to inject the implementation into the lister. As a result I think we need a more specific name for this pattern. *Inversion of Control* is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name **Dependency Injection**. I'm going to start by talking about the various forms of dependency injection, but I'll point out now that that's not the only way of removing the dependency from the application class to the plugin implementation. The other pattern you can use to do this is *Service Locator*…" [[9]](#6-references)
66 |
67 | ##### Definition
68 |
69 | - If you control the flow and when to call methods, you are in control. But when methods are called by system etc… defined by system decision instead of me (I give control to system, so it decides), then I don’t have control. This is **inversion of control**. [[11]](#6-references)
70 |
71 | - *Frameworks* often use IOC, their methods are called within the framework instead of user invoking each one of them when desired. This is the main difference between *framework* and *library*. Libraries have methods, called by users whenever desired, that does some work and returns result and control to the user again. [[11]](#6-references)
72 |
73 | - “A framework embodies some abstract design, with more behavior built in. In order to use it you need to insert your behavior into various places in the framework either by subclassing or by plugging in your own classes. The framework's code then calls your code at these points.” [[11]](#6-references) (e.g. android framework widgets having listener so you can override and write logic. Then framework invokes your code when listener condition call is met internally).
74 |
75 | - Another example: “So in JUnit, the framework code calls setUp and tearDown methods for you to create and clean up your text fixture. It does the calling, your code reacts - so again control is inverted.” [[11]](#6-references)
76 |
77 | #### b) Dependency Injection
78 |
79 | ##### Definition
80 |
81 | "The basic idea of the Dependency Injection is to have a separate object, an assembler, that populates a field in the lister class with an appropriate implementation for the finder interface." [[9]](#6-references)
82 |
83 | 
84 |
85 | Figure reference: [[9]](#6-references)
86 |
87 | "There are three main styles of dependency injection. The names I'm using for them are **Constructor Injection, Setter Injection, and Interface Injection**" [[9]](#6-references)
88 |
89 |
90 | ###### Constructor Injection
91 |
92 | There will be some configuration file (of Container, DI library or framework…) to tell which finder implementation with what parameters will be injected here. [[9]](#6-references)
93 |
94 | ```java
95 | public MovieLister(MovieFinder finder) {
96 | this.finder = finder;
97 | }
98 | ```
99 |
100 | Code Reference: [[9]](#6-references)
101 |
102 |
103 | ###### Setter Injection
104 |
105 | Again there will be configuration file that wires up right implementation (e.g. Spring framework has this option) [[9]](#6-references)
106 |
107 | ```java
108 | class MovieLister{
109 | private MovieFinder finder;
110 | public void setFinder(MovieFinder finder) {
111 | this.finder = finder;
112 | }
113 | }
114 | ```
115 |
116 | Code Reference: [[9]](#6-references)
117 |
118 |
119 | ###### Interface Injection
120 |
121 | Again there will be configuration file that sets up classes, injector and wires the implementations. (e.g. Avalon framework) [[9]](#6-references)
122 |
123 | ```java
124 | public interface InjectFinder {
125 | void injectFinder(MovieFinder finder);
126 | }
127 |
128 | class MovieLister implements InjectFinder{
129 | public void injectFinder(MovieFinder finder) {
130 | this.finder = finder;
131 | }
132 | }
133 | ```
134 |
135 | Code Reference: [[9]](#6-references)
136 |
137 | ##### Constructor vs Setter vs Interface Injection:
138 |
139 | "Interface injection is more invasive since you have to write a lot of interfaces to get things all sorted out… My long running default with objects is as much as possible, to create valid objects at construction time. This advice goes back to Kent Beck's Smalltalk Best Practice Patterns: Constructor Method and Constructor Parameter Method. Constructors with parameters give you a clear statement of what it means to create a valid object in an obvious place. If there's more than one way to do it, create multiple constructors that show the different combinations… Another advantage with constructor initialization is that it allows you to clearly hide any fields that are immutable by simply not providing a setter. I think this is important - if something shouldn't change then the lack of a setter communicates this very well. If you use setters for initialization, then this can become a pain. (Indeed in these situations I prefer to avoid the usual setting convention, I'd prefer a method like initFoo, to stress that it's something you should only do at birth.)" [[9]](#6-references)
140 |
141 |
142 | #### c) Service Locator
143 |
144 | ##### Definition
145 |
146 | - “The basic idea behind a service locator is to have an object that knows how to get hold of all of the services that an application might need. So a service locator for this application would have a method that returns a movie finder when one is needed. Of course this just shifts the burden a tad, we still have to get the locator into the lister, resulting in the dependencies of figure:” [[9]](#6-references)
147 |
148 | 
149 |
150 | Figure reference: [[9]](#6-references)
151 |
152 | - "ServiceLocator can be Singleton Registry" [[9]](#6-references)
153 |
154 | - “I've often heard the complaint that these kinds of service locators are a bad thing because they aren't testable because you can't substitute implementations for them. Certainly you can design them badly to get into this kind of trouble, but you don't have to. In this case the service locator instance is just a simple data holder. I can easily create the locator with test implementations of my services. For a more sophisticated locator I can subclass service locator and pass that subclass into the registry's class variable… A way to think of this is that service locator is a registry not a singleton. A singleton provides a simple way of implementing a registry, but that implementation decision is easily changed.” [[9]](#6-references)
155 |
156 | > **Registry**: “When you want to find an object you usually start with another object that has an association to it, and use the association to navigate to it. Thus, if you want to find all the orders for a customer, you start with the customer object and use a method on it to get the orders. However, in some cases you won't have an appropriate object to start with. You may know the customer's ID number but not have a reference. In this case you need some kind of lookup method - a finder - but the question remains: How do you get to the finder? A Registry is essentially a global object, or at least it looks like one - even if it isn't as global as it may appear.”
157 |
158 | #### Dependency Injection vs Service Locator
159 |
160 | "The important difference between the two patterns is about how that implementation is provided to the application class. With service locator the application class asks for it explicitly by a message to the locator. With injection there is no explicit request, the service appears in the application class - hence the inversion of control… Using dependency injection can help make it easier to see what the component dependencies are. With dependency injector you can just look at the injection mechanism, such as the constructor, and see the dependencies. With the service locator you have to search the source code for calls to the locator… The difference comes if the lister is a component that I'm providing to an application that other people are writing. In this case I don't know much about the APIs of the service locators that my customers are going to use. Each customer might have their own incompatible service locators." [[9]](#6-references)
161 |
162 |
163 | ## 3. Architecture Introduction
164 |
165 | - **An architecture tells us what this system does.** *“Good architectures scream their intended usage”* (e.g. you should be able to open first layer of directory system and everybody should be able to at and say “oh, that is a trading system” or “oh that is an accounting, banking system”…) And you should be able to look at single files and say “ this is where we handle deposits" [[2]](#6-references)
166 |
167 | - “When you look at a software system, and you all see is MVC in a web configuration, then the architecture of that system is hiding the use-cases of that system and exposing the delivery mechanism.” … I could dig files and understand from controllers and views that navigation flow of the app but still it is not an architecture, it does not tell me what this system does... **I should hunt to know what is the framework, is it web app… Because it is detail and it should be hidden** [[2]](#6-references)
168 |
169 | - **UI is delivery mechanism. “UI should become detail”.** [[2]](#6-references)
170 |
171 | - "**Use cases are delivery independent... It does not care about where the information comes from and it does not care where the information goes. The use case is how the system behaves with its business rules**” [[2]](#6-references)
172 |
173 | - “Use cases are **not** controllers or models in MVC” [[2]](#6-references)
174 |
175 | - “*Interactors have application specific business rules*” [[2]](#6-references)
176 |
177 | - **An architect should defer decisions of databases, frameworks…** Because if you decide it right away, you have minimum amount of information to make decision. What database where are going to use? Is this going to be web system? Is this going to be sql or nosql? that is a detail, delay that. “I do not need to start my project with all the tools working”. Important decisions (iteration zero) are VCS, programming language and how to defer other decisions about tools… [[2]](#6-references)
178 |
179 | - “A good architecture maximizes the number of decisions not made” [[2]](#6-references)
180 |
181 | - “**Make delivery mechanism (web, console, mobile) a plugin to your application (use cases, business entities)**”… [[2]](#6-references)
182 |
183 | - **To delay things turn them into plug-in. (e.g.turn database to a plugin)** [[2]](#6-references)
184 |
185 |
186 | ## 4. Clean Architecture
187 |
188 | 
189 |
190 | Figure reference: [[3]](#6-references)
191 |
192 | "Each of these architectures produce systems that are:
193 |
194 | - **Independent of Frameworks.** The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints.
195 |
196 | - **Testable.** The business rules can be tested without the UI, Database, Web Server, or any other external element.
197 |
198 | - **Independent of UI.** The UI can change easily, without changing the rest of the system. A Web UI could be replaced with a console UI, for example, without changing the business rules.
199 |
200 | - **Independent of Database.** You can swap out Oracle or SQL Server, for Mongo, BigTable, CouchDB, or something else. Your business rules are not bound to the database.
201 |
202 | - **Independent of any external agency.** In fact your business rules simply don’t know anything at all about the outside world." [[3]](#6-references)
203 |
204 |
205 | #### The Dependency Rule
206 |
207 | - "The outer circles are *mechanisms*. The inner circles are *policies (plan)*." [[3]](#6-references)
208 |
209 | - "The overriding rule that makes this architecture work is The Dependency Rule. *This rule says that source code dependencies can only point inwards. Nothing in an inner circle can know anything at all about something in an outer circle.* In particular, **the name of something declared in an outer circle must not be mentioned by the code in an inner circle.** That includes, functions, classes. variables, or any other named software entity." [[3]](#6-references)
210 |
211 | - "By the same token, data formats used in an outer circle should not be used by an inner circle, especially if those formats are generate by a framework in an outer circle. **We don’t want anything in an outer circle to impact the inner circles.**" [[3]](#6-references)
212 |
213 |
214 | #### a) Entities
215 |
216 | "Entities encapsulate Enterprise wide business rules. *An entity can be an object with methods, or it can be a set of data structures and functions…* If you don’t have an enterprise, and are just writing a single application, then these entities are the business objects of the application. They encapsulate the most general and high-level rules. They are the least likely to change when something external changes…" [[3]](#6-references)
217 |
218 | #### b) Use Cases
219 |
220 | "The software in this layer contains application specific business rules. It encapsulates and implements all of the use cases of the system. **These use cases orchestrate the flow of data to and from the entities, and direct those entities to use their enterprise wide business rules to achieve the goals of the use case.**" [[3]](#6-references)
221 |
222 | "**We do not expect changes in this layer to affect the entities. We also do not expect this layer to be affected by changes to externalities such as the database, the UI, or any of the common frameworks.** This layer is isolated from such concerns. We do, however, expect that changes to the operation of the application will affect the use-cases and therefore the software in this layer. If the details of a use-case change, then some code in this layer will certainly be affected." [[3]](#6-references)
223 |
224 |
225 | #### c) Interface Adapters (Presenter, Controller, Gateway)
226 |
227 | "The software in this layer is a **set of adapters that convert data from the format most convenient for the use cases and entities, to the format most convenient for some external agency such as the Database or the Web.** It is this layer, for example, that will wholly contain the MVC architecture of a GUI. **The Presenters, Views, and Controllers all belong in here…**" [[3]](#6-references)
228 |
229 | #### d) Frameworks and Drivers (UI, DB (infrastructure))
230 |
231 | "The outermost layer is **generally composed of frameworks and tools such as the Database, the Web Framework, etc.** Generally you don’t write much code in this layer other than glue code that communicates to the next circle inwards. This layer is where all the details go. *The Web is a detail. The database is a detail…*" [[3]](#6-references)
232 |
233 | ---
234 | “…You may find that you need more than just these four. There’s no rule that says you must always have just these four. However, The Dependency Rule always applies. Source code dependencies always point inwards. As you move inwards the level of abstraction increases. The outermost circle is low level concrete detail. As you move inwards the software grows more abstract, and encapsulates higher level policies. The inner most circle is the most general.” [[3]](#6-references)
235 |
236 | “You can use basic structs or simple Data Transfer objects if you like. Or the data can simply be arguments in function calls. Or you can pack it into a hashmap, or construct it into an object. **The important thing is that isolated, simple, data structures are passed across the boundaries.** We don’t want to cheat and pass Entities or Database rows. **We don’t want the data structures to have any kind of dependency that violates The Dependency Rule.**” [[3]](#6-references)
237 |
238 |
239 | ## 5. Clean Architecture for Android
240 |
241 | "The general structure for an Android app looks like this:
242 |
243 | - **Outer layer packages:** UI, Storage, Network, etc.
244 |
245 | - **Middle layer packages:** Presenters, Converters (mappers)
246 |
247 | - **Inner layer packages:** Interactors (use cases), Models, Repositories (interfaces only), Executor" [[6]](#6-references)
248 |
249 |
250 | #### a) Outer Layer
251 |
252 | "... this is where the framework details go.
253 | - **UI**- This is where you put all your Activities, Fragments, Adapters and other Android code related to the user interface.
254 |
255 | - **Storage**- Database specific code that implements the interface our Interactors use for accessing data and storing data. This includes, for example, ContentProviders or ORM-s such as DBFlow.
256 |
257 | - **Network**- Things like Retrofit go here." [[6]](#6-references)
258 |
259 |
260 | #### b) Middle Layer
261 |
262 | "Glue code layer which connects the implementation details with your business logic.
263 |
264 | - **Presenters**— Presenters handle events from the UI (e.g. user click) and usually serve as callbacks from inner layers (Interactors).
265 |
266 | - **Converters**— Converter objects are responsible for converting inner models to outer models and vice versa." [[6]](#6-references)
267 |
268 |
269 | #### c) Inner Layer
270 |
271 | "The core layer contains the most high-level code. All classes here are POJOs. Classes and objects in this layer have no knowledge that they are run in an Android app and can easily be ported to any machine running JVM.
272 |
273 | - **Interactors**— These are the classes which actually contain your business logic code. These are run in the background and communicate events to the upper layer using callbacks. They are also called **UseCases** in some projects (probably a better name). It is normal to have a lot of small Interactor classes in your projects that solve specific problems. This conforms to the Single Responsibility Principle and in my opinion is easier on the brain.
274 |
275 | - **Models**— These are your business models that you manipulate in your business logic.
276 |
277 | - **Repositories**— This package only contains *interfaces* that the database or some other outer layer implements. These interfaces are used by Interactors to access and store data. This is also called a repository pattern." [[6]](#6-references)
278 |
279 | ---
280 | In the Android community, layers above mentioned are not used ("outer layer", "middle layer" and "inner layer"). But instead layers (packages or android modules precisely) below is used.
281 |
282 | 
283 |
284 | Figure reference: [[5]](#6-references)
285 |
286 | #### Presentation layer
287 | - “In here, where the logic related with views and animations happens. It uses no more than a Model View Presenter (MVP from now on), but you can use any other pattern like MVC or MVVM. I will not get into details on it, but here fragments and activities are only views, there is no logic inside them other than UI logic, and this is where all the rendering stuff takes place.” [[5]](#6-references)
288 |
289 | #### Domain layer
290 | - “Business rules here: all the logic happens in this layer. Regarding the android project, you will see all the interactors (use cases) implementations here as well. This layer is a pure java module without any android dependencies. All the external components use interfaces when connecting to the business objects.” [[5]](#6-references)
291 |
292 | - "Interactors shouldn’t know anything about Android. There are ways to do threads only using Java, but even Android tools can be used by using dependency inversion. Core can use Android functions via interfaces and dependency injection. Your framework layer can implement an interface with the methods you need in your interactor. You could, for instance, wrap an AsyncTask with a core class, use that core class as the basis of asynchronous calls, and communicate back via Callbacks or an event bus" [[1]](#6-references)
293 |
294 | #### Data layer
295 | - “All data needed for the application comes from this layer through a UserRepository implementation (the interface is in the domain layer) that uses a Repository Pattern with a strategy that, through a factory, picks different data sources depending on certain conditions. For instance, when getting a user by id, the disk cache data source will be selected if the user already exists in cache, otherwise the cloud will be queried to retrieve the data and later save it to the disk cache. The idea behind all this is that the data origin is transparent for the client, which does not care if the data is coming from memory, disk or the cloud, the only truth is that the data will arrive and will be got.” [[5]](#6-references)
296 |
297 | - Unaware of presentation layer but aware of framework, tools...
298 |
299 | - Repository is **only way to access and modify** the Data. You can add, change, swap data sources in Repository and whoever uses Repository won't be affected. If an Entity can be get from different data sources (network, DB) inside Repository, make DB single source of truth and save data from network in DB and only get data from DB.
300 |
301 | Dependency may look like `Presentation -> Domain -> Data` but it is not correct. To explain layers more in "cleanish" way, this figure is better illustration:
302 |
303 | 
304 |
305 | As you can see, it makes sense to separate "Infrastructure" (as in Onion architecture) and "UI, Framework" into different modules (layers) even they stay on same layer in Clean Architecture. "Infrastructure" implements "Repository Interfaces" and "UI, Framework" depends on "Interface Adapters". "Interface Adapters" could be separated in separate module (layer) to force pure java (kotlin) code.
306 |
307 | > **Repository definition**: "A system with a complex domain model often benefits from a layer, such as the one provided by Data Mapper (165), that isolates domain objects from details of the database access code. In such systems it can be worthwhile to build another layer of abstraction over the mapping layer where query construction code is concentrated. This becomes more important when there are a large number of domain classes or heavy querying. In these cases particularly, adding this layer helps minimize duplicate query logic. A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes. Conceptually, a Repository encapsulates the set of objects persisted in a data store and the operations performed over them, providing a more object-oriented view of the persistence layer. Repository also supports the objective of achieving a clean separation and one-way dependency between the domain and data mapping layers" [[7]](#6-references)
308 |
309 | > From the definition above (2nd sentence), repository can have query construction. Also repository is needed when heavy querying is done or too many domain classes. 3rd sentence says it helps to minimize query duplication. It does not say it is the only reason to use Repository. But it helps to achieve this aim (it can hold single addPerson(id) method in repository so everybody uses this method and no addPerson query logic is duplicated). From 6th sentence, you pass the query, parameter, argument declaratively, which means you do not say how you do it (imperative). So it does not have to be sql query! From 8th sentence repository is over data source and abstract it, so domain classes don’t depend on any implementation detail of data source.
310 |
311 |
312 | ## 6. References
313 |
314 | [1] A. Leiva, "MVP for Android: how to organize the presentation layer," 15 04 2014. [Online]. Available: https://antonioleiva.com/mvp-android/. [Accessed 14 06 2017].
315 |
316 | [2] Robert C. Martin, "Clean Architecture," NDC Conferences (https://vimeo.com/43612849), 2012.
317 |
318 | [3] Ubcle Bob (Robert C. Martin), "The Clean Architecture," 13 08 2012. [Online]. Available: https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html. [Accessed 26 02 2018].
319 |
320 | [4] Jeffrey Palermo, "The Onion Architecture : part 1," 29 07 2008. [Online]. Available: http://jeffreypalermo.com/blog/the-onion-architecture-part-1/. [Accessed 26 02 2018].
321 |
322 | [5] Fernando Cejas, "Architecting Android...The clean way?," 3 09 2014. [Online]. Available: https://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/. [Accessed 26 02 2018].
323 |
324 | [6] Dario Miličić, "A detailed guide on developing Android apps using the Clean Architecture pattern," 3 02 2016. [Online]. Available: https://medium.com/@dmilicic/a-detailed-guide-on-developing-android-apps-using-the-clean-architecture-pattern-d38d71e94029. [Accessed 26 02 2018].
325 |
326 | [7] Martin Fowler, "Repository," [Online]. Available: https://martinfowler.com/eaaCatalog/repository.html. [Accessed 02 03 2018].
327 |
328 | [9] Martin Fowler, "Inversion of Control Containers and the Dependency Injection pattern," 23 01 2004. [Online]. Available: https://martinfowler.com/articles/injection.html. [Accessed 02 03 2018].
329 |
330 | [10] Martin Fowler, David Rice, "Plugin," [Online]. Available: https://martinfowler.com/eaaCatalog/plugin.html. [Accessed 02 03 2018].
331 |
332 | [11] Martin Fowler, "InversionOfControl," 26 06 2005. [Online]. Available: https://martinfowler.com/bliki/InversionOfControl.html. [Accessed 02 03 2018]
333 |
334 | [12] Martin Fowler, "Registry," [Online]. Available: https://martinfowler.com/eaaCatalog/registry.html. [Accessed 02 03 2018]
335 |
--------------------------------------------------------------------------------
/media_files/clean_architecture.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/clean_architecture.jpg
--------------------------------------------------------------------------------
/media_files/clean_architecture_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/clean_architecture_android.png
--------------------------------------------------------------------------------
/media_files/cleanish_android.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/cleanish_android.png
--------------------------------------------------------------------------------
/media_files/cleanish_android.xml:
--------------------------------------------------------------------------------
1 | 7Vzbcts2EP0azaQP8fAu6dGWndYzcZOJ27R9hEmIRA0RLAhFUr++IAHwToWyYCmuaD+YXAAEtWfPHixIeWIvVtufKUiiBxJAPLGMYDuxbyeWZRn2lP/JLDthMaeWIywhRYG0lYZH9C+URkNa1yiAaa0jIwQzlNSNPolj6LOaDVBKNvVuS4LrsyYghC3Dow9w2/oHClgkrDPXKO2/QBRGambTkC1PwH8OKVnHcr6JZS/zH9G8Aupasn8agYBsKib7bmIvKCFMHK22C4gz5yq3iXEfelqL+6YwZkMGWHMx4hvAa6huOb8xtlPOgHFwnfmUn8Uk5sabAKQRzK5g8pOIrbA8FENh0HJueTtm8SF59ECygozueJdN6WXl5KjiYGWjEAOGvtUvDyTYYXG5YobPBPGJLUPGoTM36kNSsqY+lL2qblIDZUhPbTmw70IM0BCy1oX4QeVjlqYchW5E1EyXgYhtaEKkdSF9iJjWJSEyd/UA0ryOPjy64PAwy9zMP60XstzLwvJEmxZ+9Wq3Bo556s5hM3jzJkIMPibAz1o3XOvqUKaMkme4IJjQfLTt5T+8ZYkwrtiXbvZbzPcNUga3h8IvBziNTCTdXAmOIoVUo8Ns8qMaCTUw9uWmAzy/JHl0LIXzuPWfdSZqN18hDUAMSkMu48pVpZETeprrZmkSE9zHSwq469c+W1NYgVXMeAjaHAV2LKQAozDmNp/jB3njTYYu4kuJa9mwQkGQTdgZTfV4O194uBqiw2lnRZ7lHuUpoSwiIYkBviutjc9fAQJuEfszM19Zrjz9S/binqC7alt2rhr/hozt5IISrBnhpnLmj4Qk8vp9cPYHwNDEzT2Qp8waZUT2q5jaAA7O20PxcHvZmvSQtYROkS5reJ/m7rzmHUwn2bYZecuP+N0YC+BHUBz+CtmG0Gdx8gFhaf4CE5IiRujufpVguOKe45+ZxKL1N77ET/nfd5++PKiRFD6BFF5dXf30faYnF0z0+UCiexqIPrtsAbbOqMBd5drJFfj3e8lOClZQ0HwUYR0hokOF1RbKhclwVXPnbc2dD4ZQuwyb5nAdThMQv1yHr31+44jtBDuv44ASfhM1ntZkFpMwRHEorCFGgdJZsMpoET+lSZ3F4vYuXHet8wmvOR2Vt+L6Il+eRHrNQ5Y9UnsHyuowjf5uVrCsrqxwn9Emn4DnhAAkGYlGvdYTWFoEe37xgq2oVVVsZTuHZKtweH3J/kxhKjggKmg+hhKM1flXBDfy8doownsIW+z+n0KFrf4F3UWocKO2cU4pwlnXcxbALxXhcuOLdykUOR2FWE9s6dBhtVV7wTqs2FXVYWU7iw73b2FfRKZtbiOdNtV65021cq8xzeqWBUjHZKktPLRky+mYLb2ObOmdMVv2b1BorlryBQzw+XImFXVKXqPI4+rqxnjH+UsfeAYIIS0aGk/zxoKmg8vzExY0dldB0/B5GoEkO8Qofq77figHexh1/hefel5gco9+WfAVXg7cU/5YR2iyGPhpnW9EGB/BbtAeofVihsp35KrklCadvKy9gqeBpFO3HiGeddXe/J93kdTtD8bBJN3z8tXx0D8Ir47YD8Xe8qanBN95TfDv43jk/QHYO+5Jse+qw5pLb4xRkvZ5Z99C6WnmOq5RtKhvO1jdKB3jTEWc9sLGNrtqWC0rmz0PTPt401me+r5hZEX18TuBara1MtwCBjrIt+5g3lslpAYOzusUfG+2w8jsWhxaGqJI1dU/chTJB0nybcoxmvZHk+3atXAyp10ZvTOgXA0p3RlQcL2FlK682ZDHjodx3rQrxc90kPMFJdHJUzxZATTSckAgNUrw2cAsr4OU9pCvQp6IlJTITG7fzuavk/LUBm51HeZ1uNZ2PQ0k7apfmr4tv0LnY5CmyK+7dPKD7x+5tqM0ZNfw56E7SK5dv1Cxs69/R8npesT2v0fGbCaMlyLTepaiEZkhdd8bR4bjoAuZYqB2zvDT8gv5onv5bw/su/8A
--------------------------------------------------------------------------------
/media_files/configuration_change.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/configuration_change.png
--------------------------------------------------------------------------------
/media_files/configuration_change_simpler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/configuration_change_simpler.png
--------------------------------------------------------------------------------
/media_files/ioc.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/ioc.jpg
--------------------------------------------------------------------------------
/media_files/ioc_inject.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/ioc_inject.jpg
--------------------------------------------------------------------------------
/media_files/ioc_sl.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/ioc_sl.jpg
--------------------------------------------------------------------------------
/media_files/model2_mvc.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/model2_mvc.png
--------------------------------------------------------------------------------
/media_files/model2_mvc_sequence.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/model2_mvc_sequence.png
--------------------------------------------------------------------------------
/media_files/mvc_jsp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvc_jsp.png
--------------------------------------------------------------------------------
/media_files/mvc_mvp_mvvm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvc_mvp_mvvm.png
--------------------------------------------------------------------------------
/media_files/mvc_original.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvc_original.png
--------------------------------------------------------------------------------
/media_files/mvc_vs_mvp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvc_vs_mvp.png
--------------------------------------------------------------------------------
/media_files/mvp_android_diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvp_android_diagram.png
--------------------------------------------------------------------------------
/media_files/mvp_passive_view.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvp_passive_view.png
--------------------------------------------------------------------------------
/media_files/mvp_supervising_controller.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvp_supervising_controller.png
--------------------------------------------------------------------------------
/media_files/mvvm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvvm.png
--------------------------------------------------------------------------------
/media_files/mvvm_viewmodel_scope.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/mvvm_viewmodel_scope.png
--------------------------------------------------------------------------------
/media_files/onion_architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/onion_architecture.png
--------------------------------------------------------------------------------
/media_files/presentation_patterns.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/presentation_patterns.png
--------------------------------------------------------------------------------
/media_files/save_restore_options.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jemshit/Android_Architecture_Notes/d8d40d0dd2156a27f1ebabd050ddd91c066be5e5/media_files/save_restore_options.png
--------------------------------------------------------------------------------
/mvc_cheatsheet.md:
--------------------------------------------------------------------------------
1 | # MVC (Model-View-Controller)
2 |
3 | ## 1. Original definition
4 | > Original paper [link](http://heim.ifi.uio.no/~trygver/2007/MVC_Originals.pdf)
5 |
6 | "He originally defined Models, Views, and Controllers like this:
7 |
8 | - **Models** – *Models represent knowledge.* A model could be a single object (rather uninteresting), or it could be some structure of objects.
9 |
10 | - **Views** - *A view is a (visual) representation of its model*. It would ordinarily highlight certain attributes of the model and suppress others. *It is thus acting as a presentation filter*.
11 |
12 | - **Controllers** - *A controller is the link between a user and the system*. It provides the user with input by arranging for relevant views to present themselves in appropriate places on the screen. It provides means for user output by presenting the user with menus or other means of giving commands and data. The controller receives such user output, translates it into the appropriate messages and passes these messages on to one or more of the views." [[5]](#4-references) (Controller does not update view directly though)
13 |
14 |
15 | ## 2. Original definition interpretation
16 |
17 | #### a) By Stephen Walther
18 |
19 | "In the context of a Graphical User Interface, the Model View Controller pattern was interpreted like this:
20 |
21 | - **Model** - *A particular piece of data* represented by an application. For example, weather station temperature reading.
22 |
23 | - **View** - *One representation of data from the model.* **The same model might have multiple views associated with it.** For example, a temperature reading might be represented by both a label and a bar chart. **The views are associated with a particular model through the Observer relationship.**
24 |
25 | - **Controller** - **Collects user input and modifies the model.** For example, the controller might collect mouse clicks and keystrokes and update the Model." [[5]](#4-references)
26 |
27 | 
28 |
29 | Figure reference: [[5]](#4-references)
30 |
31 | "Notice, in this figure, **that the View is updated indirectly from the Model.** When the Model changes, the Model raises an event, and the View changes in response to the event. Also, **notice that the Controller does not interact directly with the View.** Instead, the Controller modifies the Model, and since the View is observing the Model, the View gets updated. According to Martin Fowler, the primary benefit of this original version of the MVC pattern is *Separated Presentation* (which is described below)..." [[5]](#4-references)
32 |
33 |
34 | #### b) By Martin Fowler
35 |
36 | Lets start with data states before explanation:
37 | - **Record state** (copy of data in database) [[1]](#4-references)
38 |
39 | - **Session state** (in-memory record sets in application. “Essentially this provides a temporary local version of the data that the user works on until they save, or commit it, back to the database - at which point it merges with the record state.”) [[1]](#4-references)
40 |
41 | - **Screen state** (inside the GUI components themselves) [[1]](#4-references)
42 |
43 | Now lets check definition of **Data Binding** to understand one way of *synchronization between states of data* mentioned above:
44 | - "A mechanism that ensures that any change made to the data in a *UI control (screen state)* is automatically carried over to the underlying *session state* (and vice versa)”. [[2]](#4-references)
45 | - “Keeping screen state and session state synchronized is an important task. A tool that helped make this easier was Data Binding. The idea was that any change to either the control data, or the underlying record set was immediately propagated to the other. So if I alter the actual reading on the screen, the text field control effectively updates the correct column in the underlying record set." [[1]](#4-references)
46 | - "In general data binding gets tricky because if you have to avoid cycles where a change to the control, changes the record set, which updates the control, which updates the record set... The flow of usage helps avoid these - we load from the session state to the screen when the screen is opened, after that any changes to the screen state propagate back to the session state. It's unusual for the session state to be updated directly once the screen is up. As a result *data binding might not be entirely bi-directional* - just confined to initial upload and then propagating changes from the controls to the session state.” [[1]](#4-references)
47 | - “Simple data edits are handled through data binding. **Complex changes are done in the form's event handling methods.**” [[1]](#4-references) So if input data is just propagated, data binding is perfect solution. But if there is complex logic before propagating input data from user to domain layer, then you have to handle input event manually and send it to domain layer.
48 |
49 | > **Controls definiton:** UI widget controls (text changed, button pressed…) ("The form observes the controls and has handler methods to react to interesting events raised by the controls.") [[1]](#4-references)
50 |
51 |
52 | ##### Interpretation:
53 |
54 | - “At the heart of MVC, and the idea that was the most influential to later frameworks, is what I call **Separated Presentation**. The idea behind Separated Presentation is to make a *clear division between domain objects that model our perception of the real world, and presentation objects that are the GUI elements we see on the screen*. **Domain objects should be completely self contained and work without reference to the presentation, they should also be able to support multiple presentations**, possibly simultaneously. This approach was also an important part of the Unix culture, and continues today allowing many applications to be manipulated through both a graphical and command-line interface." [[1]](#4-references)
55 |
56 | - In MVC, the **domain element is referred to as the model**. *Model objects are completely ignorant of the UI…* In MVC I'm assuming a Domain Model of regular objects, rather than the Record Set notion that I had in Forms and Controls. This reflects the general assumption behind the design. Forms and Controls assumed that most people wanted to easily manipulate data from a relational database, MVC assumes we are manipulating regular... objects.” [[1]](#4-references)
57 |
58 | - “… **The controller's job** is to take the user's input and figure out what to do with it.” [[1]](#4-references) But in web app (Model2 MVC or Front Controller Pattern), controller has url routes bla bla...
59 |
60 | - “You'll notice that the text field controller didn't set the value in the view itself, it updated the model and then just let the observer mechanism take care of the updates. This is quite different to the forms and controls approach where the form updates the control and relies on data binding to update the underlying record-set. These two styles I describe as patterns: **Flow Synchronization** and **Observer Synchronization**. These two patterns describe alternative ways of handling the triggering of synchronization between *screen state* and *session state*. Forms and Controls do it through the flow of the application manipulating the various controls that need to be updated directly. **MVC does it by making updates on the model and then relying of the observer relationship to update the views that are observing that model…** The classic MVC example was a spreadsheet like screen of data with a couple of different graphs of that data in separate windows. The spreadsheet window didn't need to be aware of what other windows were open, *it just changed the model and Observer Synchronization took care of the rest…* While Observer Synchronization is nice it does have a downside... Observer behavior is hard to understand and debug because it's implicit behavior.” [[1]](#4-references)
61 |
62 | - “The Presentation Model works well also for another presentation logic problem - **presentation state.** The basic MVC notion assumes that all the state of the view can be derived from the state of the model. In this case how do we figure out which station is selected in the list box? The **Presentation Model** solves this for us by giving us a place to put this kind of state. A similar problem occurs if we have save buttons that are only enabled if data has changed - again that's state about our interaction with the model, not the model itself.” [[1]](#4-references)
63 |
64 | > "**Flow Synchronization** is a very simple approach to explain. Essentially each time you do something that changes state that's shared across multiple screens, you tell each screen to update itself. The problem is that this means, in general, that every screen is somewhat coupled to the other the other screens in the application. If you have a lot of screens that are working in a very open-ended way, this can be nasty - which is Observer Synchronization is such a strong alternative." [[3]](#4-references)
65 |
66 | > "**Observer Synchronization:** Synchronize multiple screens by having them all be observers to a shared area of domain data... Observer Synchronization uses a single area of domain oriented data and has each screen be an observer of that data. Any change in one screen propagates to that domain oriented data and thence to the other screens. This approach was a large part of the Model View Controller approach... Even the screen that makes the change doesn't need to refresh itself explicitly, since the observer mechanism will trigger the refresh in the same way as if another screen made the change." [[4]](#4-references)
67 |
68 |
69 | ##### Soundbites on MVC:
70 |
71 | - **Separated Presentation**: Make a strong separation between presentation *(view & controller)* and domain *(model)* [[1]](#4-references)
72 |
73 | - "**Divide GUI widgets into** a *controller* **(for reacting to user stimulus)** and *view* (for displaying the state of the model). **Controller and view should (mostly) not communicate directly but through the model.**" [[1]](#4-references)
74 |
75 | - **Observer Synchronization**: Have views (and controllers) observe the model to allow multiple widgets to update without needed to communicate directly. [[1]](#4-references)
76 |
77 |
78 | #### c) By Manoj Jaggavarapu
79 | "In MVC pattern, model, view, controller triad exists for each object that can be manipulated by the user. Lets see what each of these does
80 |
81 | - **Model :** Model means data, that is required to display in the view. It can sometimes be the exact data entities that are retrieved from the business layer or a variation of it. *Model encapsulates business tier.*
82 |
83 | - **View :** *View is something that displays data to user.* In MVC pattern view should be simple and free of business logic implementation. *View invokes methods on Controller depending on user actions.* **In MVC pattern View monitors the model for any state change and displays updated model.** Model and View interact with each other using the Observer pattern.
84 |
85 | - **Controller:** Controller is invoked by view, *it executes interacts with the model and performs actions that updates the model.* Controller doesn’t have an idea about the changes that it’s updates on the model resulted in the view. Often misunderstood in MVC pattern is the role of Controller. **It doesn’t mediate between the view and model, and its not responsible for updating the view. It simply process the user action and updates model,** its the view’s job to query and get the status of the changed model and render it. **The only time Controller comes into picture is if a new view has to be rendered.**" [[6]](#4-references)
86 |
87 |
88 | ## 3. Evolution
89 |
90 | JavaServer Pages (JSP) had Model 2 method for creating application. In this method, "... the components of an MVC application work like this:
91 | - Model - Business logic plus one or more data sources such as a relational database.
92 |
93 | - View - The user interface that displays information about the model to the user.
94 |
95 | - Controller - The flow-control mechanism means by which the user interacts with the application...
96 |
97 | **In this new version of the MVC model, there is no longer any relationship between the View and the Model. All communication between View and Model happens through the controller...** Several web application frameworks have adopted the Model 2 MVC pattern. In the Java world, these frameworks include Struts, Tapestry, and Spring. In the Ruby world, these frameworks include Ruby on Rails and Merb. In the Python world, these frameworks include Django. And, of course, in the ASP.NET world, these frameworks include ASP.NET MVC." [[5]](#4-references)
98 |
99 | 
100 |
101 | Figure reference: [[5]](#4-references)
102 |
103 | "In Model 2 pattern, **all web post requests go to front controller**, implemented as a http interceptor (http module in ASP.NET ), **which in turn figures out the appropriate controller depending on the structure of the incoming request URL** and services the request. The controller invokes a method that affects the model. The following diagram depicts the structure of Model2 pattern:" [[6]](#4-references)
104 |
105 | 
106 |
107 | Figure reference: [[6]](#4-references)
108 |
109 | "The main difference between classic MVC and Model2 is that **there is no direct contact between view and model. The Model in this pattern is not your typical business entities or Business layer, it’s more of a ViewModel** that captures the state of the view. **The controller will be the one who will talk to BLL and update the model. The interaction between the view and model is an indirect relationship.** Below sequence diagram depicts Model2 interactions using sequence diagram." [[6]](#4-references) View knows what model is going to be shown but does not query model or does not knwo how to query model. Also model does not have reference to view. Controller updates model and renders view with new appropriate model.
110 |
111 | 
112 |
113 | Figure reference: [[6]](#4-references)
114 |
115 |
116 | ## 4. References
117 |
118 | [1] Martin Fowler, "GUI Architectures," 18 07 2006. [Online]. Available: https://martinfowler.com/eaaDev/uiArchs.html. [Accessed 26 02 2018].
119 |
120 | [2] Martin Fowler, "Data Binding," 25 05 2006. [Online]. Available: https://martinfowler.com/eaaDev/DataBinding.html. [Accessed 26 02 2018].
121 |
122 | [3] Martin Fowler, "Flow Synchronization," 15 11 2004. [Online]. Available: https://martinfowler.com/eaaDev/FlowSynchronization.html. [Accessed 02 03 2018].
123 |
124 | [4] Martin Fowler, "Observer Synchronization," 08 09 2004. [Online]. Available: https://martinfowler.com/eaaDev/MediatedSynchronization.html. [Accessed 02 03 2018].
125 |
126 | [5] Stephen Walther, "The Evolution of MVC," 24 08 2008. [Online]. Available: http://stephenwalther.com/archive/2008/08/24/the-evolution-of-mvc. [Accessed 02 03 2018].
127 |
128 | [6] Manoj Jaggavarapu, "Presentation Patterns : MVC, MVP, PM, MVVM," 02 05 2012. [Online]. Available: https://manojjaggavarapu.wordpress.com/2012/05/02/presentation-patterns-mvc-mvp-pm-mvvm/. [Accessed 03 03 2018].
129 |
--------------------------------------------------------------------------------
/mvp_cheatsheet.md:
--------------------------------------------------------------------------------
1 | # MVP (Model-View-Presenter)
2 |
3 | > Potel paper link: http://www.wildcrest.com/Potel/Portfolio/mvp.pdf
4 |
5 | ## Introduction
6 |
7 | - "MVP is a *user interface architectural pattern* engineered to
8 | facilitate automated unit testing and improve the *separation of
9 | concerns in presentation logic*" [[1]](#7-references).
10 |
11 | - It makes code **understandable,
12 | decoupled, testable and maintainable** (easy to refactor).
13 | "Android bundles the UI and UI logic into the Activity class, which
14 | necessitates Instrumentation to test the Activity. Since Instrumentation
15 | is introduced, it is much more difficult (or impossible) to properly
16 | unit test your UI logic when the dependencies in the code cannot be
17 | mocked" [[2]](#7-references).
18 |
19 | - In MVP, application is divided into at least 3 layers
20 | and makes them independently testable from each other.
21 | "With MVP we are able to take most of logic out from the activities so
22 | that we can test it without using instrumentation tests" [[3]](#7-references).
23 |
24 | - "...One common attribute of MVP is that there has to be a **lot of two-way dispatching.** For example, when someone clicks the "Save" button, the event handler delegates to the Presenter's "OnSave" method. Once the save is completed, the Presenter will then call back the View through its interface so that the View can display that the save has completed." [[19]](#7-references)
25 |
26 | Flow goes like: **User-\> View-\> Presenter-\> Model(-\> Presenter-\> View)**
27 |
28 | 
29 |
30 | Figure Reference: [[4]](#7-references)
31 |
32 | - "When control goes from View to Presenter and then from Presenter to
33 | Model it is just a direct flow, it is easy to write code like this. You
34 | get an easy '*User -> View -> Presenter -> Model -> Data*' sequence.
35 | But when control goes like this: '*User -> View -> Presenter -> View
36 | -> Presenter -> Model -> Data*', it just violates KISS principle.
37 | **Don't play ping-pong between your view and presenter**" [[6]](#7-references).
38 |
39 |
40 | ## 1. Model
41 |
42 | - It is **Data of UI** [[2]](#7-references) [[7]](#7-references). "The model is the data that will be displayed in the view. Please note that the word 'Model' is misleading. *It should rather be business logic that retrieves or manipulates a Model*" [[5]](#7-references). "**It is an interface responsible for managing data**. Model's responsibilities include using APIs, caching data, managing databases and so on. **The model can also be an interface that communicates with other modules in charge of these
43 | responsibilities...** *If you are using the Clean architecture, the Model
44 | could be an Interactor*" [[8]](#7-references) [[6]](#7-references) [[3]](#7-references).
45 |
46 | - **Model knows nothing about other layers**. "It is best to set up the
47 | Model Layer in such a way that the Presenter does not know whether it is
48 | getting the data from the disk, memory, or network" [[9]](#7-references).
49 |
50 | - **Why have different Entity (model) for each layer?** We might get
51 | UserEntity which has name, surname from API but when displaying to UI,
52 | we may need to show full name and ranking etc. which does not come from
53 | API. Entity in Presentation may need to have such additional fields.
54 | Transformation is done asynchronously in Presenter [[5]](#7-references). Other use cases can be some annotations on fields, model must implement or extend ORM class/Android class (e.g. Parcelable), fields for (UI) state... which some other layers do not care about [[16]](#7-references).
55 |
56 | ## 2. Presenter
57 |
58 | - "Presenter is a layer that provides View with data from Model.
59 | Presenter also handles background tasks" [[6]](#7-references). It is **Logic of UI** [[2]](#7-references).
60 |
61 | - "The Presenter is the 'middle-man' (played by the controller
62 | in MVC) and has references to both, view and model" [[5]](#7-references). "**It retrieves data from the model and returns it *formatted* to the view**. *Decides the actions to take when input events are received*" [[10]](#7-references).
63 |
64 | - **No Android code here** [[8]](#7-references), it will make platform independent and no instrumentation test is required. "As far as tests are concerned, most of the code that you absolutely need to test will be in the Presenter. What's great is that all this code doesn't need Android to run, as it just has a reference to the View interface, and not its Android-specific implementation. This means that you can just mock the View interface, and write pure JUnit tests that make sure the right methods are called on that mock to test the *integrity* of your business logic" [[10]](#7-references).
65 |
66 | - "*Lifecycle events* methods on the Presenter are simple and don't have
67 | to map the (overly complicated) Android lifecycle ones. You don't have
68 | to implement any of them, but you can implement as many as you want if
69 | the Presenter needs to take specific actions" [[10]](#7-references) [[8]](#7-references). "Presenters do not need lifecycle callbacks from Activity, Fragment. It just needs to know if View is attached or not" [[11]](#7-references).
70 |
71 | - "**Android Services** are a fundamental part of android app development... Therefore it's obvious that the Presenter is responsible to communicate with the Service" [[12]](#7-references).
72 |
73 | - "**Don't retain presenter...** I think that presenter is not
74 | something we should persist, it is not a data class, to be clear... the
75 | presenter survives to orientation changes, but when Android kills the
76 | process and destroys the Activity, the latter will be recreated together
77 | with a new presenter. For this reason, this solution solves only half of
78 | the problem". You should cache in Model layer [[9]](#7-references) [[13]](#7-references). But this way you won't save ongoing network requests. **Presenter is only for UI logic, not data logic (cache).**
79 |
80 | ## 3. View
81 |
82 | - **Display of UI** [[2]](#7-references). "View is a layer that *displays data* and *reacts to user actions*" [[6]](#7-references) [[5]](#7-references). "On Android, this could be an Activity, a Fragment, an android.view.View or a Dialog" [[6]](#7-references) [[7]](#7-references). "*The View doesn't know anything about the business logic or how to get the data* it has to show to the user... It will not contain any functional or business logic like access to database or web server for example" [[14]](#7-references). "View layer with MVP becomes so simple, so it does not even need to have callbacks when requesting for data" [[6]](#7-references). **View never calls Model directly**.
83 |
84 | - *Responsibilities of View are as follows:* informing presenter of relevant
85 | lifecycle events (attach, detach), informing presenter of user input
86 | events, laying out view and binding data to them, animations, navigating
87 | to other screens [[10]](#7-references).
88 |
89 | - "*The view should concern only about any necessary request parameters
90 | to restore the state*" [[8]](#7-references). It shouldn't save presenter or data itself.
91 |
92 | #### a) Passive View
93 | - "The View is only doing what the Presenter tells the View to do. This
94 | variant of Model-View-Presenter is called **Passive View**. The view
95 | should be as dumb as possible. Let the Presenter control the view in an
96 | abstract way. For instance: Presenter invokes 'view.showLoading()' but
97 | Presenter should not control view specific things like animations. So
98 | Presenter should not invoke methods like 'view.startAnimation()' etc. By
99 | implementing MVP Passive View it's much easier to handle concurrency and
100 | multithreading. (returning data from Async calls)" [[5]](#7-references).
101 |
102 | - Make View Passive, "if you have a username/password form and a "submit" button, you don't write the validation logic inside the view but inside the
103 | presenter. Your view should just collect the username and password and
104 | send them to the presenter" [[8]](#7-references).
105 |
106 | - "You can also move all the way to having the presenter do all the manipulation of the widgets. This style, which I call **Passive View** isn't part of the original descriptions of MVP but got developed as people explored *testability issues*. I'm going to talk about that style later, but that style is one of the flavors of MVP.” [[17]](#7-references)
107 |
108 | 
109 |
110 | Figure reference: [[18]](#7-references)
111 |
112 | #### b) Supervising Controller
113 |
114 | - "The direction behind Bower and McGlashan was what I'm calling **Supervising Controller**, where the view handles a good deal of the view logic that can be described **declaratively** and the presenter then comes in to handle more **complex cases.**" [[17]](#7-references)
115 |
116 | - "The MVP pattern can also be implemented such that the View knows of
117 | the model. The view responds to state changes in the model **for simple UI updates**, while the presenter handles more complex UI logic. This more complex pattern is sometimes referred to as **Supervising Controller**. In Android, this can be accomplished by the Model using Java's Observable class and the View implementing the Observer interface; when something changes in the Model, it can call the Observable's notifyObservers method. It can also be implemented with Android's Handler class; when something changes in the Model, it can send a message to a handler that the View injects into it" [[2]](#7-references).
118 |
119 | 
120 |
121 | Figure reference: [[18]](#7-references)
122 |
123 | ##### Why do I need to define interfaces for the View ?
124 |
125 | - "*Since it's an interface you can change the view implementation*.
126 | You can simple move your code from something that extends Activity
127 | to something that extends Fragment." [[5]](#7-references)
128 |
129 | - "Modularity: You can move the whole business logic, Presenter and
130 | View Interface in a standalone library project. Then you can use
131 | this library with the containing Presenter in various apps." [[5]](#7-references)
132 |
133 | - "*You can easily write unit tests since you can mock views by
134 | implement the view interface*. One could also introduce a java
135 | interface for the Presenter to make unit testing by using mock
136 | Presenter objects even more easy." [[5]](#7-references)
137 |
138 | - "Another very nice side effect of defining an interface for the
139 | view is that you don't get tempted to call methods of the activity /
140 | fragment directly from Presenter. You get a clear separation because
141 | while implementing the Presenter the only methods you see in your
142 | IDE's auto completion are those methods of the view interface. From
143 | our personal experiences we can say that this is very useful
144 | especially if you work in a team." [[5]](#7-references)
145 |
146 | - "The methods to update the View (in View Interface) should be simple
147 | and targeted on a single element. This is better than having a single
148 | setMessage(Message m) method that will update everything, because
149 | **formatting what should be displayed should be the responsibility of the Presenter.** For example, you might want to start displaying 'You'
150 | instead of the user name if the current user is the author of the
151 | message, and this is part of your business logic" [[10]](#7-references).
152 |
153 |
154 | ##### MVP soundbites:
155 |
156 | - "User gestures are handed off by the widgets to a Supervising Controller. (a presenter)" [[17]](#7-references)
157 |
158 | - "The presenter coordinates changes in a domain model." [[17]](#7-references)
159 |
160 | - "Different variants of MVP handle view updates differently. These vary from using. Observer Synchronization to having the presenter doing all the updates with a lot of ground in-between." [[17]](#7-references)
161 |
162 |
163 | ## 4. Solutions for Orientation Change problem:
164 |
165 | - Using static Presenter to retain Presenter
166 |
167 | - Using Singleton PresenterManager class and retaining Presenters. Presenters store loaded models and returns them after orientation change [[10]](#7-references) [[6]](#7-references)
168 |
169 | - Using LoaderManager to retain Presenter. This way ongoing network requests do not get lost [[15]](#7-references)
170 |
171 | - Retain Presenter until View totally gets destroyed
172 |
173 | - Caching API response Observables in LRUCache [[9]](#7-references)
174 |
175 | - Storing API request Observables in somewhere (not to make requests twice)
176 |
177 | - Caching API response data in cache, database, file...
178 |
179 | - Request parameters for Presenter are saved in View (Activity...) [[6]](#7-references)
180 |
181 | - Save View's state (loading, showing error...) inside View (Activity...) itself
182 |
183 | - Use Architecture Component's *ViewModel* as Presenter (attach, detach View when configuration change occurs) [[20]](#7-references)
184 |
185 |
186 | ## 5. Code Repositories
187 |
188 | - https://github.com/remind101/android-arch-sample *(Uses PresenterManager for retaining Presenter)*
189 |
190 | - http://konmik.com/post/introduction_to_model_view_presenter_on_android/ *(Keeps loaded models in Presenter and returns it after orientation change. Presenter request parameters are stored in onSaveInstanceState() of Activity etc.)*
191 |
192 | - https://github.com/antoniolg/androidmvp
193 |
194 | - https://github.com/michal-luszczuk/tomorrow-mvp *(Uses LoaderManager to retain Presenter)*
195 |
196 | - https://github.com/czyrux/MvpLoaderSample *(Uses Loader to retain Presenter)*
197 |
198 | - https://github.com/macoscope/RoomBookerMVP
199 |
200 | - https://github.com/teegarcs/RetroRx *(Caches API response Observables in LRUCache)*
201 |
202 | - https://github.com/grandstaish/hello-mvp *(Retains Presenter until View gets destroyed once and for all)*
203 |
204 | - https://github.com/MindorksOpenSource/android-mvp-architecture
205 |
206 |
207 | ## 6. Bonus
208 |
209 | #### a) Configuration Change
210 |
211 | 
212 |
213 | Reference: [[6]](#7-references)
214 |
215 | - "Case 1: A configuration change normally happens when a user flips
216 | the screen, changes language settings, attaches an external monitor,
217 | etc.
218 |
219 | - Case 2: An Activity restart happens when a user has set 'Don't keep
220 | activities' checkbox in Developer's settings and another activity
221 | becomes topmost.
222 |
223 | - Case 3: A process restart happens if there is not enough memory and
224 | the application is in the background." [[6]](#7-references)
225 |
226 | ###### Simpler version
227 |
228 | 
229 |
230 | Reference: [[6]](#7-references)
231 |
232 | "Now it looks much better. We only need to write two pieces of code to
233 | completely restore an application in any possible case:
234 |
235 | - save/restore for Activity, View, Fragment, DialogFragment
236 |
237 | - restart background requests in case of a process restart" [[6]](#7-references)
238 |
239 | #### b) Presenter save/restore options
240 |
241 | 
242 |
243 | Reference: [[15]](#7-references)
244 |
245 | "Assumptions:
246 |
247 | - Presenters should live in the memory only as long as the components
248 | they belong to
249 |
250 | - The Presenter should be retained on configuration changes -- i.e. if we want to retain long running tasks (even if an activity is being recreated in the same moment)
251 |
252 | - The Presenter should be destroyed if a related component like activity or fragment is destroyed, either because of memory running out problem or just because of user action -- we don't want to needlessly waste memory and store presenter in memory if related activity/fragment is currently not there
253 |
254 | - The Presenter should be recreated after process recreation (if process of our app was killed because of low memory issues) -- we must ensure reliability and possibility to restore presenter state later even if process is destroyed" [[15]](#7-references)
255 |
256 | ## 7. References
257 |
258 | [1] "Model-View-Presenter," [Online]. Available:
259 | https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93presenter.
260 | [Accessed 16 06 2017].
261 |
262 | [2] Jeff Angelini, "An Mvp Pattern for Android," 10 04 2015. [Online]. Available:
263 | https://magenic.com/thinking/an-mvp-pattern-for-android. [Accessed 15 06 2017].
264 |
265 | [3] Antonio Leiva, "MVP for Android: how to organize the presentation layer," 15 04 2014. [Online]. Available:
266 | https://antonioleiva.com/mvp-android/. [Accessed 14 06 2017].
267 |
268 | [4] Chris Ripple, "Applying MVP in Android," 26 05 2016. [Online]. Available:
269 | http://www.goxuni.com/673883-applying-mvp-in-android/. [Accessed 16 06
270 | 2017].
271 |
272 | [5] Hannes Dorfmann, "Model-View-Presenter," 25 05 2015. [Online]. Available: http://hannesdorfmann.com/mosby/mvp/. [Accessed 14 06 2017].
273 |
274 | [6] Konstantin Mikheev, "Introduction to Model View Presenter on Android," 23 03 2015. [Online]. Available:
275 | http://konmik.com/post/introduction_to_model_view_presenter_on_android/. [Accessed 14 06 2017].
276 |
277 | [7] Piotr Ziomacki, "Model-View-Presenter Architecture in Android Applications," 14 01 2016. [Online]. Available:
278 | http://macoscope.com/blog/model-view-presenter-architecture-in-android-applications/. [Accessed 15 06 2017].
279 |
280 | [8] Francesco Cervone, "Model-View-Presenter: Android guidelines," 27 02 2017. [Online]. Available:
281 | https://medium.com/@cervonefrancesco/model-view-presenter-android-guidelines-94970b430ddf. [Accessed 15 06 2017].
282 |
283 | [9] Clinton Teegarden, "A MVP Approach to Lifecycle Safe Requests with Retrofit 2.0 and RxJava," 11 02 2016. [Online]. Available:
284 | https://www.captechconsulting.com/blogs/a-mvp-approach-to-lifecycle-safe-requests-with-retrofit-20-and-rxjava. [Accessed 15 06 2017].
285 |
286 | [10] Nathan Barraille, "Android Code That Scales, With MVP," remind.com, 12 2 2015. [Online]. Available:
287 | http://engineering.remind.com/android-code-that-scales/. [Accessed 14 06 2017].
288 |
289 | [11] Hannes Dorfmann, "Presenters don't need lifecycle," 24 04 2016. [Online]. Available:
290 | http://hannesdorfmann.com/android/presenters-dont-need-lifecycle.
291 | [Accessed 14 06 2017].
292 |
293 | [12] Hannes Dorfmann, "STINSON'S PLAYBOOK FOR MOSBY," 09 05 2015. [Online]. Available:
294 | http://hannesdorfmann.com/android/mosby-playbook. [Accessed 14 06 2017].
295 |
296 | [13] Mike Nakhimovich, "Presenters are not for persisting," 22 01 2017. [Online]. Available:
297 | https://hackernoon.com/presenters-are-not-for-persisting-f537a2cc7962.
298 | [Accessed 15 06 2017].
299 |
300 | [14] David Guerrero, "A BRIEF INTRODUCTION TO A CLEANER ANDROID ARCHITECTURE: THE MVP PATTERN," 13 10 2015. [Online].
301 | Available:
302 | https://davidguerrerodiaz.wordpress.com/2015/10/13/a-brief-introduction-to-a-cleaner-android-architecture-the-mvp-pattern/. [Accessed 15 06 2017].
303 |
304 | [15] Michał Łuszczuk, "MVP for Android," 19 04 2016. [Online]. Available:
305 | http://blog.propaneapps.com/android/mvp-for-android/. [Accessed 15 06 2017].
306 |
307 | [16] Joe Birch, "Android Do you even map though? Data model mapping in Android Apps" 21 12 2017. [Online]. Available:
308 | https://overflow.buffer.com/2017/12/21/even-map-though-data-model-mapping-android-apps/. [Accessed 22 02 2018].
309 |
310 | [17] Martin Fowler, "GUI Architectures," 18 07 2006. [Online]. Available: https://martinfowler.com/eaaDev/uiArchs.html. [Accessed 26 02 2018].
311 |
312 | [18] Manoj Jaggavarapu, "Presentation Patterns : MVC, MVP, PM, MVVM," 02 05 2012. [Online]. Available: https://manojjaggavarapu.wordpress.com/2012/05/02/presentation-patterns-mvc-mvp-pm-mvvm/. [Accessed 03 03 2018].
313 |
314 | [19] "What are MVP and MVC and what is the difference?," [Online]. Available: https://stackoverflow.com/a/101561/3736955. [Accessed 03 03 2018].
315 |
316 | [20] Jose Alcérreca, "ViewModels and LiveData: Patterns + AntiPatterns," [Online]. Available: https://medium.com/@JoseAlcerreca/yep-if-you-use-viewmodel-as-a-presenter-you-need-a-reference-to-the-view-b853879ccd0e. [Accessed 21 03 2018].
317 |
--------------------------------------------------------------------------------
/mvvm_cheatsheet.md:
--------------------------------------------------------------------------------
1 | # MVVM (Model-View-ViewModel)
2 |
3 | "Model/View/ViewModel is a variation of Model/View/Controller (MVC) that is tailored for modern UI development platforms
4 | where the View is the responsibility of a designer rather than a classic developer.
5 | The designer is generally a more graphical, artistic focused person, and does less classic coding than a traditional developer..
6 | The design is almost always done in a declarative form like HTML or XAML.." [[8]](#references).
7 | "Just like its MVC predecessor, the View in MVVM can bind to the data and display updates, but without any coding at all,
8 | just using XAML markup extensions. This way, the View is under the designer’s control, but can update its state from the
9 | domain classes using the WPF binding mechanism. This fits the description of the Presentation Model pattern." [[9]](#references).
10 |
11 | 
12 | [[1]](#references)
13 |
14 | - "Model-View-ViewModel is an architectural approach used to **abstract the state and behaviour of a view**, which allows us to **separate the development of the UI from the business logic.**" [[2]](#references)
15 | - "This is accomplished by the introduction of a ViewModel, whose responsibility is to expose the data objects of a model and handle any of the application logic involved in the display of a view." [[2]](#references)
16 |
17 | ## 1. Model
18 |
19 | - "Data model containing business and validation logic" [[1]](#references) [[2]](#references)
20 | - Does not contain any View reference or View related logic
21 |
22 |
23 | ## 2. View
24 |
25 | - "Defines the structure, layout and appearance of a view on screen" [[2]](#references)
26 | - "View in MVVM is similar to view in PM. It contains only the UI elements. The interaction between View and ViewModel happens using Data Binding, Commands and Notifications..." [[1]](#references)
27 | - "..ViewModel only provides the data, whereas the View is responsible for consuming them." [[5]](#references)
28 | - In Android, View can consume data using _LifecycleOwner_ and _LiveData_ classes, which stops observing (unsubscribes/disposes) the data at corresponding lifecycles automatically
29 | - "Even if the View gets to decide how to handle data, that does not mean it needs to contain complicated logic. The idea is that ViewModel provides data in a form that View **simply takes and display** - no manipulation required." [[5]](#references)
30 |
31 |
32 | ## 3. ViewModel
33 |
34 | - "Acts a link between the View and Model, dealing with any view logic" [[2]](#references)
35 | - "ViewModel does not hold reference to the View" [[5]](#references)[[7]](#references)
36 | - "View Model is equivalent to PresentationModel in PM pattern, it encapsulates presentation logic and data for the view. ViewModel contains the state of the view and uses Commands, DataBinding and Notifications to communicate with the view." [[1]](#references)
37 | - "Keep the ViewModel free of Android Dependencies...This allows me to utilize JUnit unit tests for a quick feedback loop" [[3]](#references)[[7]](#references)
38 | - "ViewModels hold **transient data used in the UI**, but they don’t persist data" [[6]](#references)
39 | - ViewModel class offered by Android survives configuration change (screen rotation) (using Retaining Fragment under the hood). So it can hold UI state [[4]](#references)[[5]](#references)[[7]](#references)
40 |
41 | 
42 | [[4]](#references)
43 |
44 | - For one-off events (like Toast message), PublishSubject (RxJava) or SingleLiveEvent (Lifecycle Components) [[7]](#references) classes can be used.
45 | - It can be used by multiple Views
46 | - ViewModel can expose _ObservableInterface>_ to hold information about loading, success, error instead of just data. [[7]](#references)
47 |
48 |
49 | ### DataBinding
50 |
51 | Pros:
52 | - Reduces boilerplate, because it binds view and logic directly without middle man
53 |
54 | Cons:
55 | - In Android, requires full package name to ViewModel class in XML
56 | - In Android, containing logic in XML is not good, it makes testing difficult. Instead, these logics can be moved to custom _BindingAdapters_ [[3]](#references)
57 | - If you want to have click listener for Android View, function in ViewModel has to return _View.OnClickListener_, which forces ViewModel to have Android code
58 |
59 |
60 | ### References
61 |
62 | [1] Manoj Jaggavarapu, "Presentation Patterns : MVC, MVP, PM, MVVM," 02 05 2012. [Online]. Available: https://manojjaggavarapu.wordpress.com/2012/05/02/presentation-patterns-mvc-mvp-pm-mvvm/. [Accessed 03 03 2018].
63 |
64 | [2] Joe Birch, "Approaching Android with MVVM" 21 09 2015. [Online]. Available: https://labs.ribot.co.uk/approaching-android-with-mvvm-8ceec02d5442. [Accessed 21 10 2020].
65 |
66 | [3] Donn Felker, "Android MVVM with DataBinding – Removing Logic from Your Views with BindingAdapters". [Online]. Available: https://www.donnfelker.com/android-mvvm-with-databinding-removing-logic-from-your-views-with-bindingadapters/. [Accessed 21 10 2020].
67 |
68 | [4] Luis G. Valle, "Firebase, ViewModels & LiveData" 22 10 2017. [Online]. Available: https://medium.com/@lgvalle/firebase-viewmodels-livedata-cb64c5ee4f95. [Accessed 21 10 2020].
69 |
70 | [5] Kamil Seweryn, "MVP to MVVM transformation" 20 01 2018. [Online]. Available: https://proandroiddev.com/mvp-to-mvvm-transformation-611959d5e0ca. [Accessed 21 10 2020].
71 |
72 | [6] Lyla Fujiwara, "ViewModels: Persistence, onSaveInstanceState(), Restoring UI State and Loaders" 17 07 2017. [Online]. Available: https://medium.com/androiddevelopers/viewmodels-persistence-onsaveinstancestate-restoring-ui-state-and-loaders-fc7cc4a6c090. [Accessed 21 10 2020].
73 |
74 | [7] Jose Alcérreca, "ViewModels and LiveData: Patterns + AntiPatterns" 12 09 2017. [Online]. Available: https://medium.com/androiddevelopers/viewmodels-and-livedata-patterns-antipatterns-21efaef74a54. [Accessed 21 10 2020].
75 |
76 | [8] John Gossman, "Introduction to Model/View/ViewModel pattern for building WPF apps" 08 10 2015. [Online]. Available: https://docs.microsoft.com/en-us/archive/blogs/johngossman/introduction-to-modelviewviewmodel-pattern-for-building-wpf-apps. [Accessed 21 10 2020].
77 |
78 | [9] alexy.shelest, "Model View Controller, Model View Presenter, and Model View ViewModel Design Patterns" 03 10 2009. [Online]. Available: https://www.codeproject.com/Articles/42830/Model-View-Controller-Model-View-Presenter-and-Mod. [Accessed 21 10 2020].
--------------------------------------------------------------------------------
/pattern_differences.md:
--------------------------------------------------------------------------------
1 | #### Why use patterns?
2 | > "Well one can certainly build software applications without using any of these patterns, but by using these patterns we can achieve *separation of concerns* design principle. These help in improving maintainability of the application. Another important reason why these patterns became popular is implementing these patterns improve the testability of the application using automated unit tests." [[2]](#3-references)
3 |
4 |
5 | ## 1. Overview
6 |
7 | 
8 |
9 | Figure Reference: [[2]](#3-references)
10 |
11 |
12 | ## 2. Differences
13 |
14 | 
15 |
16 | Figure Reference: [[1]](#3-references)
17 |
18 | #### a) MVC
19 |
20 | "Let’s look at MVC first. You’ll notice a few things about the diagram:
21 |
22 | - The input is directed at the Controller first, not the view. That input might be coming from a user interacting with a page, but it could also be from simply entering a specific url into a browser. In either case, its a Controller that is interfaced with to kick off some functionality.
23 |
24 | - There is a many-to-one relationship between the Controller and the View. That’s because a single controller may select different views to be rendered based on the operation being executed.
25 |
26 | - Note the one way arrow from Controller to View. This is because the View doesn’t have any knowledge of or reference to the controller.
27 |
28 | - The Controller does pass back the Model, so there is knowledge between the View and the expected Model being passed into it, but not the Controller serving it up.
29 |
30 | - ... When you first try to access an MVC application, you would type something like this: 'www.somewebsite.com/customers'. When that request comes in, the MVC routing engine determines which controller "customers" refers to and directs it to the proper or default method. Its within that method where its determined what view should be rendered. Let's say you clicked a link on the rendered view to 'www.somewebsite.com/customerlist'. Same thing happens - the routing engine determines which controller "customerlist" is referring to and that controller determines which view gets rendered. That's one of the biggest diferences between MVC and traditional ASP.NET webform apps - you're not navigating to the location of a page in a folder structure, you're passing a request to a controller that determines what gets rendered... The view knows information about what model its being passed for binding purposes. However, the **view doesn't know how to get the model or what context the model is in as far as state**. It only knows that it can expect a Customer object, for example, and it has helpers to bind properties of the customer to itself." [[1]](#3-references)
31 |
32 | - "**In the MVC, the Controller is responsible for determining which View to display in response to any action** including when the application loads. *This differs from MVP where actions route through the View to the Presenter.* **In MVC, every action in the View correlates with a call to a Controller along with an action.** In the web each action involves a call to a URL on the other side of which there is a Controller who responds. Once that Controller has completed its processing, it will return the correct View. The sequence continues in that manner throughout the life of the application:
33 | Action in the View -> Call to Controller -> Controller Logic -> Controller returns the View.
34 | One other big difference about MVC is that the View does not directly bind to the Model. **The view simply renders, and is completely stateless.** *In implementations of MVC the View usually will not have any logic in the code behind. This is contrary to MVP where it is absolutely necessary because, if the View does not delegate to the Presenter, it will never get called.*" [[3]](#3-references)
35 |
36 | - "...**in MVC, controller methods are based on behaviors** -- in other words, *you can map multiple views (but same behavior) to a single controller.* **In MVP, the presenter is coupled closer to the view, and usually results in a mapping that is closer to one-to-one,** i.e. a view action maps to its corresponding presenter's method. You typically wouldn't map another view's actions to another presenter's (from another view) method." [[4]](#3-references)
37 |
38 | #### b) MVP
39 |
40 | "Now let’s look at the MVP pattern. It looks very similar to MVC, except for some key distinctions:
41 |
42 | - The input begins with the View, not the Presenter.
43 |
44 | - There is a one-to-one mapping between the View and the associated Presenter.
45 |
46 | - The View holds a reference to the Presenter. The Presenter is also reacting to events being triggered from the View, so its aware of the View its associated with.
47 |
48 | - The Presenter updates the View based on the requested actions it performs on the Model, but the View is not Model aware." [[1]](#3-references)
49 |
50 | - “The first element of Potel is to treat the view as a structure of widgets, widgets that correspond to the controls of the Forms and Controls model and *remove any view/controller separation*. **The view of MVP is a structure of these widgets. It doesn't contain any behavior that describes how the widgets react to user interaction.** *The active reaction to user acts lives in a separate presenter object. The fundamental handlers for user gestures still exist in the widgets, but these handlers merely pass control to the presenter*. The presenter then decides how to react to the event…” [[6]](#3-references)
51 |
52 | - "MVP uses a Supervising Controller (a presenter when view is dumb) to manipulate the model. **Widgets hand off user gestures** to the Supervising Controller. *Widgets aren't separated into views and controllers.* You can think of presenters as being like controllers but without the initial handling of the user gesture. However it's also important to note that presenters are typically at the form level, rather than the widget level - this is perhaps an even bigger difference." [[6]](#3-references)
53 |
54 | - "...Furthermore the presenter is welcome to directly access widgets for behaviors that don't fit into the Observer Synchronization." [[6]](#3-references)
55 |
56 | - "From our point of view *MVP is not a variant or enhancement* *of MVC* because that would mean that the Controller gets replaced by the Presenter. In our opinion **MVP wraps around MVC**. Take a look at your MVC powered app. The Presenter sits in the middle between controller and model like this:" [[5]](#3-references)
57 |
58 | 
59 |
60 | Figure reference: [[5]](#3-references)
61 |
62 | - "In our opinion the *Presenter does not replace the Controller*. Rather the Presenter coordinates or supervises **the View which the Controller is part of**. The Controller is the component that handles the click events and calls the corresponding Presenter methods. The Controller is the responsible component to control animations like hiding ProgressBar and displaying ListView instead. The Controller is listening for scroll events on the ListView i.e. to do some parallax item animations or scroll the toolbar in and out while scrolling the ListView. **So all that UI related stuff still gets controlled by a
63 | Controller and not by a Presenter** (i.e. *Presenter should not be an OnClickListener*). The Presenter is responsible to **coordinate the overall state** of the view layer (composed of UI widgets and Controller). So it's the job of the Presenter to tell the view layer
64 | that the loading animation should be displayed now or that the ListView should be displayed because the data is ready to be displayed" [[5]](#3-references).
65 |
66 | #### c) MVVM
67 |
68 | "So with the MVC and MVP patterns in front of us, let’s look at the MVVM pattern and see what differences it holds:
69 |
70 | - The input begins with the View, not the View Model.
71 |
72 | - While the View holds a reference to the View Model, the View Model has no information about the View. This is why its possible to have a one-to-many mapping between various Views and one View Model…even across technologies. For example, a WPF View and a Silverlight View *could* share the same View Model. However, my own feeling is that this is a bad practice and creates Franken-ViewModels that have too many responsibilities. It’s better to keep it as a one-to-one mapping instead.
73 |
74 | - You’ll also notice that the View has no idea about the Model in the MVVM pattern. This is because, as far as the View knows, its “Model” IS the View Model (hence its name). Because of how data-binding and other features like commanding work in WPF and Silverlight, there is rich communication between the View and View Model, isolating the View from having to know anything about what’s really happening behind the scenes." [[1]](#3-references)
75 |
76 | - "..ViewModel only provides the data, whereas the View is responsible for consuming them." [[7]](#references)
77 |
78 | #### d) PM
79 | Presentation Model definition: https://martinfowler.com/eaaDev/PresentationModel.html
80 |
81 | ## 3. References
82 |
83 | [1] "MVVM Compared To MVC and MVP," 21 11 2009. [Online]. Available: https://web.archive.org/web/20170829105757/http://geekswithblogs.net/dlussier/archive/2009/11/21/136454.aspx. [Accessed 03 03 2018].
84 |
85 | [2] Manoj Jaggavarapu, "Presentation Patterns : MVC, MVP, PM, MVVM," 02 05 2012. [Online]. Available: https://manojjaggavarapu.wordpress.com/2012/05/02/presentation-patterns-mvc-mvp-pm-mvvm/. [Accessed 03 03 2018].
86 |
87 | [3] "What are MVP and MVC and what is the difference?," [Online]. Available: https://stackoverflow.com/a/101561/3736955. [Accessed 03 03 2018].
88 |
89 | [4] "What are MVP and MVC and what is the difference?," [Online]. Available: https://stackoverflow.com/questions/2056/what-are-mvp-and-mvc-and-what-is-the-difference#comment67878328_101561. [Accessed 03 03 2018].
90 |
91 | [5] Hannes Dorfmann, "Model-View-Presenter," 25 05 2015. [Online]. Available: http://hannesdorfmann.com/mosby/mvp/. [Accessed 14 06 2017].
92 |
93 | [6] Martin Fowler, "GUI Architectures," 18 07 2006. [Online]. Available: https://martinfowler.com/eaaDev/uiArchs.html. [Accessed 26 02 2018].
94 |
95 | [7] Kamil Seweryn, "MVP to MVVM transformation" 20 01 2018. [Online]. Available: https://proandroiddev.com/mvp-to-mvvm-transformation-611959d5e0ca. [Accessed 21 10 2020].
--------------------------------------------------------------------------------