nab-challenge
Take home challenge from NAB in partnership with Positive Thinking Company
Software development principles, patterns and practices
Principles
- Program to an interface, not an implementation – Every methods of repository is called through Interface, not their implementation. Because of this, it is easier to add new repositories without changing the implementation
- Seperation of concerns – Seperate the app architecture into layers, each layer has its own responsibility
- Single Responsibility – One method does one thing
- Inversion of Control – Use dependency injection library Hilt to avoid dependencies between components
Patterns
- Observer Pattern – In UI Controllers, observe changes from data in ViewModel to take actions
- Factory Pattern – Use ViewModelFactory to get ViewModel instance based on the type and constructor params
- Builder Pattern – Construct Retrofit, Moshi with builder to avoid calling constructor with so many params
- Singleton Pattern – Make repositories components, API instance as singleton so that there is only one instance of these during the app lifecycle
- MVVM Pattern – Model, View, View-Model for testable code and robust architecture
Practices
- Regex – Used to validate data based on specific format
- Unit test – Make sure that functions run in right way
- Two Way data binding – When the data on the View changes, the binded property in ViewModel will update automatically
- CI/CD with Github Action – Make a build when code in this repository changes. If this fails, notify through email about the result
- DiffUtils – Improve performance of RecyclerView in Android
- Secure app – Use Proguard to minify, obfuscate code, remove unused resource for both
release
anddebug
build
Libraries & frameworks
- Github Action – Create build assembles whenever code is updated
- Timber – Logging
- Retrofit2 – Construct the REST APIs and paging network data
- Moshi – A modern JSON library for Kotlin and Java
- Hilt – A dependency injection library
- AppCompat – Degrade gracefully on older versions of Android
- Test/Junit – An Android testing framework for unit tests
- Data Binding – Declaratively bind observable data to UI elements
- Lifecycles – Create a UI that automatically responds to lifecycle events
- LiveData – Build data objects that notify views when the underlying datasource changes
- Navigation – Handle everything needed for in-app navigation
- Kotlin Coroutine – Handle long running operation outside main thread
Folder structure
data
: Contains mostly code related to acess datanetwork
: Setup code for API service along with its methods to get the datarepository
: Implementation code for the repository in the domain
di
: Dependency Injection modules that are used across the appdomain
: Contains the logic, model accross the app, related to businessdto
: Data Transfer Objects, used to receive data from remote with Json propertiesmodel
: Domain Model Objects, contain data and some logics related to the object in apprepository
: Interface only, define a contract that is needed to access datautils
: Helper methods to handle data
presentation
: Contains the logic, code to display datadailyforecast
: A screen folder, contains its related file such as ViewModel, UI Controller (Fragments, Activities), ViewModelFactoryutils
: Some base or helper methods
Setup
Run by installing APK
- Go to the list of builds created here
- Choose the latest one with green tick (Sucessfully built)
- Download the assemble.zip
- Extract downloaded file and install the APK file
Run in Android Studio
Precondition:
- Android Studio version 4.2.2 and above
- SDK version from 23 to 30
- Emulator from API 23
- Clone this project
- Open in Android Studio
- Click Run
Note for the Average Temperature calculation:
Because the Average Temperature is calculated by sum of each measurements, then divided by the times, according to the API, the Average Temperature calculation formula is as below:
Averrage Temperature = SumOf(morning, day, evening, night) / 4
Checklist
- 1. Programming language: Kotlin is required, Java is optional.
- 2. Design app’s architecture (suggest MVVM or you can use any architectures that you get
familiar) - 3. Apply LiveData mechanism or any mechanism that you get familiar with
- 4. UI should be looks like in attachment.
- 5. Write UnitTests (nice to have)
- 6. Secure Android app from:
- a. Decompile APK
- b. Rooted device (optional)
- 7. Exception handling (optional)
- 8. Readme file includes:
- a. Brief explanation for the software development principles, patterns & practices being
applied - b. Brief explanation for the code folder structure and the key Java/Kotlin libraries and
frameworks being used - c. All the required steps in order to get the application run on local computer
- d. Checklist of items the candidate has done
- a. Brief explanation for the software development principles, patterns & practices being
Video
weather-forecast.2.mp4