Skip to content

Latest commit

 

History

History
101 lines (74 loc) · 4.22 KB

README.md

File metadata and controls

101 lines (74 loc) · 4.22 KB

Dogs We Love™

Dogs We Love™ 🎉 is an app that shows a lists of dogs.

The goal of the project is to showcase my knowledge on Flutter and it's technologies. My architectural decisions followed simple principles: Simplicity, testability, modularity, scalability and maintainability to name a few.

I named simplicity first, because that is my modus operandi, that's how I usually work, that's when I feel comfortable. But don't be fooled, the project is simple yet robust. It lives on a rock-solid foundation suitable for new features, improvements and life-long development.

🏛 Architecture

Clean Architecture, SOLID Principles and Domain-Driven Design are at the core of this app's architecture. First I divided the app into 3 layers with distinct set of responsibilities. Data, Domain and Presentation.

Layers: Domain, Data, Presentation

Domain Layer

This layer is the foundation of the whole application. I started here to match my code structure to the business domain. In this case, delivering dog objects to the user. Notice that the Domain layer is independent from any other layers. Actually if we exclude Equatable, it only depends on the Dart language itself.

This approach allows the domain to be independent from the Data and Presentation layer. Ideally decisions made on what database to use or how to display the list of dogs to the user should not result in any code change to the Domain layer.

Data Layer

This layer manages data access and exposes said data using Domain's Repositories. This layer is responsible to retrieve data from the internet and/or local cache (e.g. retrofit, Floor , SharedPreferences).

We call data source any library, service or client used to retrieve data. In this app we have two data sources.

  • Remote: Implemented using retrofit, it handles http calls for us and automatically casts data into our DTOs.
  • Local: Implemented using floor, it caches remote data into a local database.

Presentation Layer

This layer is closest to what the user sees on the screen. The presentation layer is made easy by the bloc library. Even though we use the bloc library, I decided to use cubits since they are simple yet robust, following the principles mentioned above.

📚 Libraries

This project takes advantage of many popular libraries and tools in the Flutter ecosystem. Here is a list of the relevant libraries used in the project.

  • bloc: A predictable state management library that helps implement the BLoC (Business Logic Component) design pattern.
  • flutter_bloc: Easy to implement the BLoC (Business Logic Component) design pattern.
  • google_fonts: Fonts from fonts.google.com in your Flutter app.
  • retrofit: An dio client generator using source_gen and inspired by Chopper and Retrofit.
  • get_it: A simple Service Locator for Dart and Flutter.
  • equatable: Value based equality without needing to explicitly override == and hashCode.
  • mocktail: A Dart mock library which simplifies mocking with null safety support and no manual mocks or code generation.

🧪 Coverage

To calculate the coverage you should have lcov in your computer. If that is not the case, you can install it by running the following command. ⚠️ Note: you should have homebrew installed.

brew install lcov

Once installed, you can run the following command at the root of the project. This will run all tests, output a lcov.info file and finally, the script will auto-magically open a report in your browser.

sh coverage.sh

👋🏼 Author

Daniel Llamas Daniel Llamas, Android Developer soyllamas.com

Made with ❤️ from Daniel.