AhmedAbdoElhawary /
flutter-clean-architecture-instagram
A full-featured Instagram clone built with Flutter, powered by Firebase for backend services and Agora for real-time video calls, offering posts, stories, chat, likes, comments, and more.
Loading repository data…
ShadyBoukhary / repository
Clean architecture flutter: A Flutter package that makes it easy and intuitive to implement Uncle Bob's Clean Architecture in Flutter. This package provides basic classes that are tuned to work with Flutter and are designed according to the Clean Architecture.
A Flutter package that makes it easy and intuitive to implement Uncle Bob's Clean Architecture in Flutter. This package provides basic classes that are tuned to work with Flutter and are designed according to the Clean Architecture.
Add this to your package's pubspec.yaml file:
dependencies:
flutter_clean_architecture: ^6.2.0
You can install packages from the command line:
with Flutter:
$ flutter packages get
Alternatively, your editor might support flutter packages get. Check the docs for your editor to learn more.
Now in your Dart code, you can use:
import 'package:flutter_clean_architecture/flutter_clean_architecture.dart';
It is architecture based on the book and blog by Uncle Bob. It is a combination of concepts taken from the Onion Architecture and other architectures. The main focus of the architecture is separation of concerns and scalability. It consists of four main modules: App, Domain, Data, and Device.
Source code dependencies only point inwards. This means inward modules are neither aware of nor dependent on outer modules. However, outer modules are both aware of and dependent on inner modules. Outer modules represent the mechanisms by which the business rules and policies (inner modules) operate. The more you move inward, the more abstraction is present. The outer you move the more concrete implementations are present. Inner modules are not aware of any classes, functions, names, libraries, etc.. present in the outer modules. They simply represent rules and are completely independent from the implementations.
The Domain module defines the business logic of the application. It is a module that is independent from the development platform i.e. it is written purely in the programming language and does not contain any elements from the platform. In the case of Flutter, Domain would be written purely in Dart without any Flutter elements. The reason for that is that Domain should only be concerned with the business logic of the application, not with the implementation details. This also allows for easy migration between platforms, should any issues arise.
Domain is made up of several things.
Login usecase expects a Repository that has login functionalityUsecases from outer layersDomain represents the inner-most layer. Therefore, it the most abstract layer in the architecture.
App is the layer outside Domain. App crosses the boundaries of the layers to communicate with Domain. However, the Dependency Rule is never violated. Using polymorphism, App communicates with Domain using inherited class: classes that implement or extend the Repositories present in the Domain layer. Since polymorphism is used, the Repositories passed to Domain still adhere to the Dependency Rule since as far as Domain is concerned, they are abstract. The implementation is hidden behind the polymorphism.
Since App is the presentation layer of the application, it is the most framework-dependent layer, as it contains the UI and the event handlers of the UI. For every page in the application, App defines at least 3 classes: a Controller, a Presenter, and a View.
View builds the page's UI, styles it, and depends on the Controller to handle its events. The View has-a Controller.View is comprised of 2 classes
View, which would be the root Widget representing the ViewViewState with the template specialization of the other class and its Controller.ViewState contains the view getter, which is technically the UI implementationStatefulWidget contains the State as per FlutterStatefulWidget only serves to pass arguments to the State from other pages such as a title etc.. It only instantiates the State object (the ViewState) and provides it with the Controller it needs through it's consumer.StatefulWidget has-a State object (the ViewState) which has-a ControllerStatefulWidget and the State are represented by a View and ViewState of the page.ViewState class maintains a GlobalKey that can be used as a key in its scaffold. If used, the Controller can easily access it via getState() in order to show snackbars and other dialogs. This is helpful but optional.ViewState has-a Controller. The Controller provides the needed member data of the ViewState i.e. dynamic data. The Controller also implements the event-handlers of the ViewState widgets, but has no access to the Widgets themselves. The ViewState uses the Controller, not the other way around. When the ViewState calls a handler from the Controller, refreshUI() can be called to update the view.Represents the data-layer of the application. The Data module, which is a part of the outermost layer, is responsible for data retrieval. This can be in the form of API calls to a server, a local database, or even both.
Repository should implement Repository from the Domain layer.polymorphism, these repositories from the data layer can be passed across the boundaries of layers, starting from the View down to the Usecases through the Controller and Presenter.Entities with the addition of extra members that might be platform-dependent. For example, in the case of local databases, this can be manifested as an isDeleted or an isDirty entry in the local database. Such entries cannot be present in the Entities as that would violate the Dependency Rule since Domain should not be aware of the implementation.Data layer will not be necessary as we do not have a local database. Therefore, it is unlikely that we will need extra entries in the Entities that are platform-dependent.Entity objects to Models and vice-versa.Entity or a Model and return the other.ModelsUtility classes if neededConstants classes if neededPart of the outermost layer, Device communicates directly with the platform i.e. Android and iOS. Device is responsible for Native functionality such as GPS and other functionality present within the platform itself like the filesystem. Device calls all Native APIs.
Repositories in Data, Devices are classes that communicate with a specific functionality in the platform.Repositories are pass across the boundaries of the layer: using polymorphism between the App and Domain layer. That means the Controller passes it to the Presenter then the Presenter passes it polymorphically to the Usecase, which receives it as an abstract class.Utility classes if neededConstants classes if neededlib/
app/ <--- application layer
pages/ <-- pages or screens
login/ <-- some page in the app
login_controller.dart <-- login controller extends `Controller`
login_presenter.dart <-- login presenter extends `Presenter`
lo
Selected from shared topics, language and repository description—not editorial ratings.
AhmedAbdoElhawary /
A full-featured Instagram clone built with Flutter, powered by Firebase for backend services and Agora for real-time video calls, offering posts, stories, chat, likes, comments, and more.
ficiverson /
This repo is a small explanation of clean architecture on with flutter framework and some test where added
shirvanie /
Controller extends the Controller abstract class, which implements WidgetsBindingObserver. Every Controller class is responsible for handling lifecycle events for the View and can override:
Controller has to implement initListeners() that initializes the listeners for the Presenter for consistency.Controller has-a Presenter. The Controller will pass the Repository to the Presenter, which it communicate later with the Usecase. The Controller will specify what listeners the Presenter should call for all success and error events as mentioned previously. Only the Controller is allowed to obtain instances of a Repository from the Data or Device module in the outermost layer.Controller has access to the ViewState and can refresh the ControlledWidgets via refreshUI().Controller has-a Presenter. The Presenter communicates with the Usecase as mentioned at the beginning of the App layer. The Presenter will have members that are functions, which are optionally set by the Controller and will be called if set upon the Usecase sending back data, completing, or erroring.Presenter is comprised of two classes
Presenter e.g. LoginPresenter
ControllerUsecase to be usedObserver<T> class and the appropriate arguments. E.g. with username and password in the case of a LoginPresenterObserver<T>
Presenter class. Ideally, this should be an inner class but Dart does not yet support them.Usecase
Usecase returns an object, it will be passed to onNext(T).onError(e).onComplete().Presenter that are set by the Controller. This way, the event is passed to the Controller, which can then manipulate data and update the ViewStateUtility classes (any commonly used functions like timestamp getters etc..)Constants classes (const strings for convenience)Navigator (if needed)Flutter Messenger Clean Architecture with Bloc, Cubit, Provider, RxDart, ObjectBox, SharedPreferences, Retrofit, Dio, GetIt(Dependency Injection) and Test with BlocTest, UnitTest, WidgetTest, IntegrationTest
iamnijat /
You can start taking control of your personal finance and monthly budget planning with Keep Money. Made with Clean architecture + Hive + flutter_bloc + GraphQL finally with 💙
mo7amedaliEbaid /
Flutter Multi Platform movies 🎬 app - clean architecture .
andrzejchm /
This repository showcases a Flutter project that implements Clean Architecture, Clean Code, and MVP pattern. It serves as a starting point for developers to learn about these concepts in Flutter, and provides a clear example of their implementation in a real-world scenario.