Half Way to clean architecture
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 18 | |
Author | ||
License | CC Attribution - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/48118 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | ||
Genre | ||
Abstract |
|
#droidconDE 201616 / 18
2
5
6
9
13
15
16
17
18
00:00
Computer architectureComputer virusLecture/Conference
00:24
Android (robot)outputTouchscreenComputer animation
00:45
Line (geometry)Profil (magazine)CodeCartesian coordinate systemService (economics)Computer animationLecture/Conference
01:06
Service (economics)Computer architectureEvent horizonError messageView (database)Service (economics)Grass (card game)Cache (computing)Multiplication signCartesian coordinate systemBus (computing)Data recoveryGreen's functionLogicDependent and independent variablesState of matterSoftwareFlow separationTouchscreenComputer animation
02:13
DataflowGreen's functionLine (geometry)Bus (computing)Classical physicsEvent horizonComputer animation
02:34
Division (mathematics)Factory (trading post)Game controllerDesign by contractCache (computing)BootingFactory (trading post)Presentation of a groupGame controllerMultiplication signStandard deviationLogicStrategy gameTask (computing)Online chatRevision controlHelmholtz decompositionLecture/Conference
03:06
Computer architectureCartesian coordinate systemFerry CorstenLecture/Conference
03:28
Rule of inferenceMultilaterationComputer architectureGreatest elementSoftwareDomain nameTransportation theory (mathematics)Data modelPresentation of a groupAnalogyDataflowBitCore dumpCuboidDirection (geometry)Endliche ModelltheorieData typeDampingComputer animation
05:50
Repository (publishing)LoginPersonal digital assistantComputer filePresentation of a groupCASE <Informatik>Content (media)PasswordView (database)Computer architecturePoint (geometry)Repository (publishing)Online chatInterface (computing)Bridging (networking)BitError messageLoginDataflowProcess (computing)TouchscreenEndliche ModelltheorieMultiplication signRight angleCodeArithmetic progressionQuery languageSystem callMappingHash functionConstructor (object-oriented programming)Cache (computing)File systemInternet service providerRule of inferenceData modelParameter (computer programming)Direction (geometry)Object (grammar)Instance (computer science)Semiconductor memorySoftware2 (number)Exception handlingDependent and independent variablesThread (computing)ResultantConnected spaceSource codeOpen sourceFlow separationCartesian coordinate systemPattern languageInterpreter (computing)Different (Kate Ryan album)Domain nameImplementationMessage passingHydraulic jumpSocial classKey (cryptography)Heegaard splittingInterior (topology)MereologyTexture mappingHierarchyDatabaseData storage deviceSelectivity (electronic)Traffic reportingGroup actionLattice (order)Insertion lossAndroid (robot)Connectivity (graph theory)Greatest elementOperator (mathematics)Real numberSquare numberGraph coloringCrash (computing)Level (video gaming)AreaRun time (program lifecycle phase)LogicGenderLecture/Conference
14:14
Moving averageSoftware testingError messagePresentation of a groupView (database)ImplementationLogicLecture/ConferenceComputer animation
14:43
Message passingMultiplication signPower (physics)Active contour modelLecture/Conference
15:04
Power (physics)Interface (computing)MereologyComputer architectureData conversionLecture/ConferenceComputer animation
15:52
Computer architectureHuman migrationAndroid (robot)FeedbackCASE <Informatik>Web 2.0CurveDifferent (Kate Ryan album)Connectivity (graph theory)Code refactoringCycle (graph theory)Multiplication signLecture/ConferenceComputer animation
16:42
Connectivity (graph theory)Software maintenanceResultantMereologyDifferent (Kate Ryan album)Data modelCodeComputer architecturePresentation of a groupStability theoryTask (computing)Interface (computing)ImplementationProcess (computing)Flow separationCartesian coordinate systemTexture mappingStandard deviationView (database)Lecture/Conference
18:13
CodeMultiplication signSampling (statistics)CodeComputer architectureSource codeMathematicsDifferent (Kate Ryan album)Code refactoringDirection (geometry)CASE <Informatik>Core dumpMereologyKey (cryptography)Software maintenanceImplementationSet (mathematics)Software bugCartesian coordinate systemRewriting1 (number)Computer animationLecture/Conference
21:07
Java appletElectric generatorEndliche ModelltheorieCodePoint (geometry)Connectivity (graph theory)Analytic continuationKeyboard shortcutAndroid (robot)Presentation of a groupComputer programmingCursor (computers)Projective planeCycle (graph theory)Control flowInternet service providerCartesian coordinate systemVideo gameBitImplementationBoilerplate (text)Module (mathematics)Source codeInterface (computing)Different (Kate Ryan album)GodComputer architectureLine (geometry)GoogolShared memorySystem callFlow separationoutputContext awarenessView (database)Revision control2 (number)Beta functionMereologyResultantResolvent formalismCASE <Informatik>Skeleton (computer programming)Computer fileState of matterStability theoryContent (media)StapeldateiObject (grammar)Lecture/Conference
Transcript: English(auto-generated)
00:01
Hello. Hello everyone. Welcome to my... Thank you so much. So today I'm going to present our way of clean architecture. And first of all you need to understand that clean architecture is not really a simple thing. And there is no one way to implement it. So today I'm going to talk about our way.
00:22
So what we did in Badu. So I'm representing here Badu. It's a social network company. It's already been said we have 100 million downloads in Android. 50 million downloads in iOS. So we're quite big. We have kind of challenges. So this is like example of what we do. So you can know what kind of screens we have.
00:43
This is like people around you. You can see the profile of a person. Or you can chat to the person. So in general in Badu we have 100,000 lines of code, more or less. 185 activities. 23 services.
01:01
4 white labels. And we have 4 applications. So long time ago when grass was green, we had very simplified architecture there. So we had like an activity, goes through event bus, to the cache, and then to network. If things was in cache, it respond immediately.
01:23
Also, we had like services connected to event bus, and the global listener which we used for notifying user with some notifications, dialects, error states, and other things. Long time ago, it was like more than six years ago, there were no auto on the market. And we based in London.
01:41
We built our own event bus. It's a double-decker from London. Okay, so during the time was passing, the application become more and more complicated. We've been facing some issues. For example, our cache become very, very complicated. Because the one cache for all screens, activities, services.
02:02
So it was very hard for us to maintain it. The other problem, when you put lots of your business logic, you put your network, error recovery, your views in the one activities become huge, very huge. And also it's a kind of a classical issue with event bus.
02:21
It's very hard to follow the data flow. So let's say we're seeing the data flow goes by green lines, but in practice it might go again somewhere else. And we didn't really want that. So one of the solution is quite obvious. We need just to apply decomposition.
02:40
And one day we did it. And this kind of the entities we end up with when we create a first version of chat. So you can see almost everything there. We have controllers, factories, presenters, caches, handlers, tasks, strategies, like lots of them.
03:01
And it was not very easy and obvious to follow the logic. So we decided it's time to do standardization. And the good solution for that would be taking something from the community. So we decided why not, we should apply clean architecture. It was quite noisy that days about clean architecture. People been looking and talking about it a lot.
03:22
So one of our guys was inspired a lot. He tried to apply. And we've been lucky that that days we started creating a new application. And we was able to try it from scratch. Okay, so this is clean architecture consists of several ideas. One of them, a core idea of clean architecture, is it built on layers.
03:41
So you need to build your software based on layers. And the rule on layers is very important. You go, data flow goes in one direction from top to the bottom. You never jump over. So layer one should not ever contact layers three directly. So if you look at the imports, we know that layer two don't import layers three.
04:02
It doesn't know about it. Layer two will never import layer one. Because data flow shouldn't go up. It should go only one direction. And layer three is the most isolated ever. Okay, and another very important thing in using layers, you need to use data models specific to that layer.
04:24
So each layer will have their own data models. And you need to convert them. I will talk a bit later in an example why we need that. And in clean architecture of our understanding in Badoo, we have three layers. One is presentation layer. Then we have domain layer.
04:41
And then we have data layer. Based on that idea, I will just go in details a bit later. So just right now let's talk about apples. This is apple farm, if you don't see it. So let's imagine we need to transport apples to our consumers. So we can have like three layers here.
05:00
Farm layer, transportation layer, and consumer layer. And let's imagine we want to transport the whole farm. We just take it from the ground and try to transport in it. It's not very efficient. It's much better to put apples in boxes and transport them. And then at the end of the day the consumer is trying to get an apple, should heat the box together with apples, with paper.
05:23
It's not very healthy. So we need to just give him the straight apple. So that's the analogy which tries to show you that each layer should have their own data models. It will save you lots and lots of efforts later when you need to migrate to some other data types,
05:40
or when you try to replace some layer. You are not really breaking anything if you just change transportation layer model. Okay, so this is the whole picture of the clean architecture we have on one of our open sourced component for chat. So I will just show you one example how data goes.
06:02
So let's imagine user wants to log in. So he just pass his details, press the button, log in. So view will notify presenter, pass some data to it, like for example, log in details, password. Then presenter will create use case parameters.
06:21
It's already in between two models, two layers, so it's a different model. It will then notify use case saying, like, create me a session or log in user. Use case will create a query and go to repository later, so it's another data model.
06:41
In repository, we'll then access data from data source. We'll return back through observable, so we decided to use Rx, and it was very, very cool and smart idea that day, so we're still very keen on the use in Rx. So as observable, we return back the results to use case, then to the presenter,
07:04
and then presenter notifies view to show user success or just switch to another screen or maybe show an error message. Okay, and I will talk a bit later in the details of all that each layer. So let's talk about data layer.
07:22
The bottom one, it represented by repository, so this is an entry point for your data. Usually, repository looks very similar to content providers in Android, so it has a couple of methods to query data, remove, insert, update. At some point, we realize it's much better to have this, only query.
07:42
And then you have specific queries to create something, remove something, update something, or select or find something. And then if you have this, you'll have much easier way of caching things. So about queries, so as an example of query, it's like a constructor.
08:02
You can create user by passing ID, name, and gender, for example, and then pass it to repository, and it will create a user for you. And if you implement equals and hash code for your query, then you can use it in hash maps. You can map query to results. So your memory cache would be super easy to implement.
08:22
And also, if you have some execution in progress right now, you can have them in another map, so you can return immediately the execution or your observable immediately to the caller, so you won't repeat the same operation several times. Another responsibility for repository is also managing threads.
08:43
So it creates the background thread and then accessing data from the data sources. So it's a host for data sources. So let's say we want to find the user. First what repository does, it checks the memory data source, these hash maps, let's say.
09:02
But it should be like a separate entity. Okay? So we check, we found a value there, we return it immediately. Otherwise, if we didn't find anything there, we can go deeper to the second data source, which is file data source, so we can access data from database, or we can access data from just file system.
09:22
Or you can even skip this, you don't have any cache in file system. So if the data is there, we just go back, update in memory data source, and return it from repository. If it's not there, we go deeper to the network layer, network data source.
09:41
So we request, receive update, update file data source, update memory data source, return to the caller. And in our implementation of clean architecture, that's kind of like a singleton we have in our hierarchy of objects. So repositories, we have one instance of each repository for each in the whole application, in the whole process.
10:05
The next layer is domain layer. In clean architecture, it's represented by use cases. It's like a dark horse of the whole architecture. There are so many ways you can mislead or you can create a different interpretation in Baddoo.
10:21
For example, we have one open source component, which built on top of clean architecture, and one application. And both of them have different ideas, what is use case and how to use it. So I will show something in general. So use case is like a business logic, and it's an entry point for data flow.
10:41
So you go through use case and then go deeper to the data. If we go to talking about examples, so let's say we have a session, and we can create session by login user, or we can destroy session by calling logout. And then use case will talk to repository.
11:01
It knows what repository to talk about. And your UI will never, ever try to access repository directly. This is because of the rule of layers. So we split it into layers, we could not overjump. If we want to logout, then use case will call delete on repository, but it's not enough.
11:23
Let's say we have a chat application, so we have lots and lots of data already stored for this particular user. User logout, we need to destroy cache. So this use case will talk to the messages use case, will never talk directly to the repository. It will talk to another use case, asking clear.
11:42
And then that use case will talk to his own repository and call delete on it. So if you do this, your flow of data is very obvious and very simple to understand and follow. And the last one is the golden part of clean architecture.
12:00
If you just switch to MVP only, you already get like 50% of all benefits. And we already started from that. I will show you why this is a key and core thing of the whole thing. So MVP is a presentational pattern which tries to separate view from model.
12:24
There is no way, there is no direct connection between view and model. All data goes through presenter. So presenter knows how to represent data and knows how to react on the user's actions. And in clean architecture models is use cases.
12:42
So this is like a bridge from one layer to another layer. If we just talking only about this area, this square, we find out it's very, very good practice to create one interface of presenter. And inside having an inner interface of a view which knows how to work with this presenter.
13:05
So you can see that all relationship and all the data flow is possible. You can see it in one file. So you can easily follow what's going on and what can be called. And the rule is the following.
13:21
You never ever call presenter methods outside the view. So nobody else except view calls presenter. The same story with the view interface. You never call view methods by the place which is not a presenter. And then you'll be successful with MVP. Okay, and having all of them as interfaces give us some benefits.
13:44
Let's imagine situation we just read about clean architecture, find out it's cool, let's try. How can we do this? So we can have one implementation of view and then we have one clean presenter instance. Then we can have legacy presenter at the same time.
14:02
So you can have even in run time, you can switch them. You can analyze and see the user activity. You can see the crashes, performance. And then based on that ideas, you can roll out slowly your new clean architecture or you can just roll it back and user will still sit on the legacy until you fix all your issues. And also for testing it's amazing.
14:22
MVP is the best ever thing for testing UI. So you can have more presenters and then you can test your UI. Another story from other side. You can have one implementation of presenter, one business logic, and then you can have, let's say, one view. Your designers decided, okay, let's show errors as a dialogues.
14:44
And then later they say, no, toast messages is better. And then Google says, no, guys, snake bar is much better. So we can have three of them at the same time and we can analyze user activity. We can analyze user satisfaction. And then we can choose only one and keep it. But still we have a chance to have three of them at the same time.
15:04
And that's the power of MVP and using interfaces. So when we've been thinking how, where to migrate and how to migrate, we've been considering following risks. First of all, clean architecture might not work for us, which in practice did work, so it's fine.
15:21
Don't worry, guys, we already stepped on the problems. I will tell later what kind of problems there. So another thing, it might be overcomplicated. So we need to do too much things to maintain it. In practice it's not. It's quite easy and simple. Another part is we've seen that we have layers, we have converting of data, so it might be slow.
15:44
And in practice it wasn't slow at all. And then the last one can be maybe boring, so people would be bored. And it's not. The people who work in the teams who work with clean architecture, they are very satisfied. So we get lots of feedback and we are very happy about this move to clean architecture.
16:04
Another thing, which we already paid, is the cost of migrating. First of all, the learning curve. So usually people, they make mistakes, they learn by mistakes. And it depends, of course, on the experience, but usually it's never the case. For example, a small kid starts walking.
16:22
He's always falling down. The same story with applying the new architecture, especially clean, which was originally created for web and then adapted to Android. There are so many different ideas how it should work. So you need to be ready for refactoring cycles. So both of our components have been refactored for five times.
16:42
And another problem is differences in ideas. I already told that even in our company, two different components have different modifications of clean architecture. And then the last funny part is that in Badu, we have a special task we give to the people who want to apply for a job.
17:04
So one guy sent us quite nicely-architectured solution. It was amazingly structured and so on. The only one small problem, he never solved the original problem. He never solved the task. So beware. And the benefits we get from migrating to clean architecture is that the stability improved like a rocket.
17:28
Before, we've been struggling how to test an application. With clean architecture, you have layers. Each layer can be replaced with mocks implementation. Then you have data models in between. So you can test in isolation easily.
17:42
MVP is amazing as well because you have interfaces everywhere. You can test presenter or you can test view without any problem. Another benefit, the huge benefit is standardization. So we have lots of new joiners these days. And for us, it's very critical to have something standardized so people know from the first day how to start doing things.
18:07
And another thing is code separation as a result of maintainability improved a lot. Our teams which work with clean architecture deliver faster, produce less bugs, and are more happier at the end.
18:22
And so how we migrated, how we started. We started from discussions. So we've been looking at our problems, deciding what can we do with that. Then we assigned two people. That's the core thing. When there are two people working on clean architecture, it's not too slow for them to do refactorings.
18:40
So let's imagine we have ten people team working at the same time, always trying to interact with each other, deciding, making some mistakes, refactoring. Two people is much better. It's much faster, but one person might be not enough because they need to discuss. Otherwise, they might end up with very weird implementation of clean architecture.
19:03
And we never rewrite anything. As I've already shown you guys, we're always keeping all the legacy implementation for some time so we know for sure that it will work. And it is not more buggier and the maintainability is better and so on. So don't rewrite. And already I told it.
19:22
We always kept the old code. And also, again, we discussed. So discussion is a key to success in every team which are more than one person. The later ones you migrated, it's not really enough to say, okay, we just did it. That's it. It's like a paradise started for us.
19:41
That's not true. You always need to work with your follow-ups to the person. So you need to fix some small mistakes. You need to update people with the new changes. And then you need to remind them what is use case, what is repository, how it's better to implement, and so on. Another thing is code reviews is a very core and important part.
20:05
During code reviews, you always adjust to each other. So in general, if you do code reviews in a team, in general, team will go in some one direction unified here. You need to have your own tutorials as well, internal tutorials.
20:22
Otherwise, people might mess up with clean architecture. You can try Google it. You'll find out many, many differences in clean architecture. It's not very easy to find one source of truth. The last thing maybe is the samples. You need to create samples so it won't be like your application as an example.
20:40
You need like a small, tiny set of examples so you know how to work, how to implement it. And the very last one is do tech talks internally so people can listen to you. And then at the end of the day, they come up with questions and you can answer them. So that's it. Danke.
21:05
Danke. I would like to be able to say Danke in Ukrainian, but what is it? Jacko. Jacko. Okay. Your questions. Wait, wait, wait. Please keep quiet for the next few minutes so that people who have questions have the chance to ask, to actually ask them.
21:26
Thank you. Hi. The question is first, you have a lot of UI, a lot of code to rewrite or write. Do you use like auto-generated code because there are a lot of boilerplate for all these view presenters and others.
21:46
Yeah, okay. So we don't really use a lot of code generation. So we start using data binding at some point. It's kind of a code generation. But then we realize we have more problems with it than benefits.
22:01
And now what we have, if you want to create the new component, we have like a special wizard in Android Studio. You create new component, it creates file skeletons for you, and then you just modify it and that's it. So something like create new activity in Android Studio. And second, so you talked about this clean architecture for Android.
22:25
And looks for the first view that you are absolutely separated from other teams like iOS, maybe web and other. Do you like share code with them? Because you have a lot of it.
22:42
Yes, so it's quite hard to share Java code with C code and vice versa. So usually what we do, we have internal tech talks and we share ideas. Usually we don't share code. Maybe we are not big enough to do this. So we have like enough resources, I would say, to solve our problems without sharing code.
23:04
But still probably not big enough. Like Google, for example, they use, as far as I know, they convert Java to Objective C. So we don't do it yet. Okay. Are you using content providers in your application? Yes, we do use content providers, and usually the idea how to use it properly is hide it in data source.
23:27
So data source gives you clean interface, but your implementation is a little bit tight to Android, so it uses content provider behind. So because you told that you are using RX Java, RX Android, reactive
23:42
programming, how do you transport cursors that you usually get from content provider? So the thing is that we'll never ever transport cursor. We always convert data to the internal models, and we can supply by pieces, for example. In the RX Java, it's possible you can subscribe to some amount of data so you can batch the result.
24:01
And we always convert and convert more and more and more data. Okay, since you need content resolver to access content provider, the only way to access it that I know is using activity. No, not really. You need just the context. You can have your application context, and then you can access data. So you pass context towards last layer?
24:22
Yes. At some point, yeah. We have to do it. Okay. Thank you. Thank you. One more question over here. One, two. Yeah. Thanks for an awesome talk.
24:41
So you mentioned code separation, so how exactly you separate a code? So you use different Gradle modules in your app, or you just use different packages, so how exactly you did that? Yes. So we use both approaches. As I said, we have differences in different implementation of clean. One application uses modules because they've been even more modern than previous applications.
25:02
So we're already steps on the problem that if you separate by packages, it's very easy to make a mistake. You need to always keep an eye on what you import. And sometimes some new joiners just join your team, don't really understand how things go, and add your dependency back from the layer and break things. So the best thing would be definitely split it by the project, sub-project.
25:26
Thank you. Question about the MVP part. So in your case, how do you tie all this stuff, presenter part in particular, with activity lifecycle? Okay, yeah. So that's quite an interesting question. We had lots of discussions about that.
25:45
So we realized that we have special marker interface, like presenter with lifecycle, and sometimes our presenter knows about lifecycle. So we have callbacks, and presenter reacts based on the state of an activity.
26:01
Thank you. And one more, final one. Yeah, clean architecture is really awesome thing. We use something almost the same as you do. My question is, when you choose MVP, did you compare it to MVVM? Yes, we started from MVVM because that day it was like a beta version of data binding.
26:25
We start using it, using, using, using. At some point we realized it's a very bad thing for us at some point. And it's much harder to test. And then another team, people start applying MVP, and we find out a big difference for the stability.
26:42
So we start migrating to MVP everywhere. Okay, that was it. Merci, thank you. Thank you.