Day 1
1. What will be changed on tests in multi-module projects
On this talk, the speaker showed me that one of the benefits from splitting the app into multiple modules that we can test the module feature without building the APK thus speed up the development time and testing time.
Currently, we mostly divided the app based on the layers like UseCase, Repo, etc.. it does also affect the how we use the DI, mainly it use to offer each component on that layer (ex: provideARepository, provideAUseCase, etc..).
Before we carry out the module separation we need to think what is goal/purpose of a module, and what is the best way to test the module, so the speaker showed that a module should group based on a feature, so the main app will be injected by Feature. (the source code it showed that the ViewModel is injected with the feature)
For the module testing, I saw that every module might have a dependency with another module, the tester suggests that each module is able to be tested independently.
New Things that I learn:
- Testing composition: Unit Test > Integration Test > UI Test
- Mutation Testing which is a test to validate our unit test (by changing the source code, it will show how the unit test responded to the code change), and one of the lib to perform a Mutation Testing is pittest and the source code is also provided an example of pittest usage on the android project.
2. Dependency Injection using Dagger2 in multi module projects
- Please note that on this talks the DI is using Dagger Android support (that use
@ContributesAndroidInjector
)
On this talks, the speaker showed me that on a Monolithic app, the steps to implement DI using Dagger is divided into:
- Module Declaration.
- Fragment Module declaration.
- Component Declaration.
- Initialize the Component on the Application#onCreate.
- Use the injection.
but on a multimodule app, we cannot inject the app with multiple components like:
onCreate() {
DaggerAComponent.create().inject(this)
DaggerBComponent.create().inject(this)
}
it will crash the app since the application can only be injected by a single component.
so the steps for DI implementation on a multimodule will be changed into this:
- Module Declaration.
- Fragment Module declaration.
- Injector Declaration. (new)
- Component Declaration. (need changes)
- Initialize the Component on the Application#onCreate (need changes).
- Use the injection.
the injector in the number 3, is a way to add injection dynamically it will extend the HasDispatchingInjector
class
the speaker also shared a glimpse about how we can use the Dynamic Injection with the Android Dynamic Feature (download part of the app when it is needed), since we cannot perform injection on the directly on Application#onCreate, we need to inject it by using the moduleFragmentInjector
- the code in the slide is quite detailed so even I did not understand Japan language understand about what it means.
3. The GREATEST usecase ever! an answer to defining business logic
On this talks the speaker sharing his experience about the difference in Business Logic, and a Use Case when working on an App (Rakuten Call). The Speaker thinks that a Business Logic is a Specification that is known by the Business Team, and the Use Case is a Business Logic that is split by Case, so a Use Case can be decided when discussing with the Business Team.
On the provided code I learn that:
- The Business Logic and The Use Case are possible to extend the same Class. (UseCase)
- Business Logic is used to define the whole flow.
- Use Case is set as a Constraint Logic.
- The Package Grouping is different between Use Case and Business Logic, although it extends the same class, so package grouping is important.
4. The good and bad of modern app architecture
The speaker shared his experience when implementing a modern app architecture (Layered Components), the important things that he shares is:
The Bad
- The layered design is not meant for a Cross-Platform solution, so in order to achieve this, it may need to break some rules on the layering.
- A layered design has a longer learning curve, so he shared that usually, it required almost 5-month adaptation for a new engineer.
- The layered design tends to create more Code, it tends to complicate and takes longer time.
- Determine a Use Case is quite tricky and if we have a gigantic Use Case. (because is associated with the whole feature on a specific Screen)
- In the Layered Design, the class/data type on each layer may not be exposed to the higher layer, this makes it complicated since it may need to add a Mapper function to map a data from the Repository layer (POJO that mapped to a certain Table) to a UseCase data type (POJO that not include all of the table structure)
The Good
- the Layered Design will produce a code that has bigger maintainability because it is easier to test, and reducing bugs.
- To implement/change a Feature it is more isolated since everything is already layered, it is easier to split the Developer task based on the layers. (a Developer can work on the View and the others can work on another layer)
5. Grid systems and Android
I attend this talk because this is a break
from the previous talks that are involving coding, it turns out the grid is very helpful it also gives me an understanding about how to implement the designer UI, and this is some note on the talk:
- 4dp Grid is used for the icon and typography, and the rest should use 8dp Grid
- Keyline is very important, it helped a lot as a reference Guide to speed up the development process, especially if we are using
ConstraintLayout
- Implement a Responsive design, by using the number of columns and combine it with the breakpoint rule.
- Tools to display Grid on the Android, so it can help to provide feedback for the Grid Implementation, like the Keyline Pushing, Material Cue, etc.
6. From Monolithic to Modularized codebase with Dagger
Since the things that commonly injected mainly are ViewModel, UseCase/Service, and Repository. The speaker suggests to group those parts in a SubComponent, each SubComponent may represent a Feature on the app, and that SubComponent may group into a Component (on the slides it called the AppComponent).
The modularization also shows some challenges like:
- Since it is possible that multiple features to access the same Data Source. (API / Repository)
- Some feature may require special android permission.
- The Feature may trigger from a BrodcastReceiver, and Service.
Based on the issue, the speaker suggested that the main app not to call the feature module directly, but create another module that will handle any feature module as an abstraction layer. (the speaker calls it a data module)
The Dynamic Module also shows some challenge since it will change how we call another Feature, one of the changes are calling another Activity by its Class Name. (using String combined with reflection)