{"id":20664042,"url":"https://github.com/flutterando/minicore","last_synced_at":"2025-03-10T09:42:04.876Z","repository":{"id":179758068,"uuid":"664092495","full_name":"Flutterando/minicore","owner":"Flutterando","description":"Flutter/Dart Architecture proposal inspired by Clean Architecture.","archived":false,"fork":false,"pushed_at":"2023-07-09T06:27:17.000Z","size":2266,"stargazers_count":46,"open_issues_count":0,"forks_count":9,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-02-01T03:54:52.229Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Flutterando.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-08T22:26:05.000Z","updated_at":"2024-11-14T12:16:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"e09b2a52-640f-4626-883a-c23a30a73c90","html_url":"https://github.com/Flutterando/minicore","commit_stats":null,"previous_names":["flutterando/minicore"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fminicore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fminicore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fminicore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Flutterando%2Fminicore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Flutterando","download_url":"https://codeload.github.com/Flutterando/minicore/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242825934,"owners_count":20191485,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T19:21:50.983Z","updated_at":"2025-03-10T09:42:04.844Z","avatar_url":"https://github.com/Flutterando.png","language":null,"readme":"# MiniCore Arch\n\nFlutter/Dart Architecture proposal inspired by Clean Architecture.\n\n![Image 1](imgs/image2.png)\n\n##  Clean Dart Proposal\n\nIf you need something more robust, try Clean Dart!\n\n- [pt-BR](1.0/README.md)\n- [en-US](1.0/README_en.md)\n\n# Start\n\nUsing Flutter as an example, we will then have three layers maintaining the “Plugin Architecture”, with the main focus on the State of the Application, which is the layer that hosts the events/actions for state changes.\n\n![Image 1](imgs/image1.png)\n\nThe Architecture proposal proposes to decouple the outermost layers and preserve the Business Rule.\n\n## UI\n\nThe **UI** Layer is responsible for declaring the application's inputs, outputs and interactions.\n\nUsing Flutter as an example, we will host the Widgets and Pages, in the backend as an example, it would be in this layer where we would place the Handlers or Commands of our API.\n\n## INTERACTOR\n\nThe **Interactor** layer will host the application's Business Rules along with their states.\nThe core of the layer will be state elaboration and scheduling through some state management approach.\n\nTaking a Repository as an example, we will only have to have the interfaces contract (Abstractions) and the responsibility for implementing this object will have to be transferred to another lower layer.\n\n## DATA\n\nThis layer supports the **Interactor** layer by implementing its interfaces. To do this, it adapts external data so that it can fulfill the domain's contracts.\n\nMost likely in this layer we will implement some Repository or Services interface that may or may not depend on external data such as an API or access to some Hardware such as Bluetooth.\n\nIn order for the Repository to be able to process and adapt external data, we must create contracts for these services in order to pass the implementation responsibility to the lowest layer of our architecture.\n\nBasically, the **DATA** layer should contain everything that will have a high chance of being changed without the programmer being able to intervene directly in the project.\n\n# Design Patterns\n\n## Isolate Layers - Service\n\nThe `Service` pattern will be used for code types that don't have a predefined pattern but need to be separated.\n\n[Service layer pattern documentation](https://en.wikipedia.org/wiki/Service_layer_pattern)\n\n## Dependency Injection\n\nNecessary to apply the Dependency Inversion Principle (DIP).\n\n[Flutterando Video - Dependency Injection](https://www.youtube.com/watch?v=KpPnDHpgHnA)\n\n## State management\n\nIn cases of multiple sucessful states the _[State Pattern](https://refactoring.guru/design-patterns/state)_ can be used:\n\n```dart\nsealed class UserState {}\n\nfinal class UnregisteredUserState implements UserState {...}\nfinal class RegisteredUserState implements UserState {...}\n```\n\nUse any state management approach to propagate states. Suggestions:\n\n- [ValueNotifier](https://api.flutter.dev/flutter/foundation/ValueNotifier-class.html?gclid=Cj0KCQjwkqSlBhDaARIsAFJANki5MzNFMZ_zHkydtK6igQyyyDdJHteXp3steWclG70LsnJYFiE98JsaAqebEALw_wcB\u0026gclsrc=aw.ds)\n- [Triple](https://triple.flutterando.com.br/)\n- [ASP](https://github.com/Flutterando/asp)\n- [BLoC/Cubit](https://bloclibrary.dev/#/)\n- [MobX](https://pub.dev/packages/mobx)\n\u003cbr\u003e\n\n\n## Adaptation and conversion\n\nData types conversion should be made using the `Adapter` pattern.\u003cbr\u003e\n\n[Adapter Pattern documentation](https://refactoring.guru/design-patterns/adapter)\n\n\u003cbr\u003e\n\n## External API Access (REST OR GRAPHQL)\n\n`Repository Pattern` with `Datasource`.\u003cbr\u003e\n[Repository Documentation form Microsoft](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design)\n\u003cbr\u003eOR\u003cbr\u003e\n\n`Gateway Pattern`.\u003cbr\u003e\n[Martin Fowler Gateway definitions](https://martinfowler.com/articles/gateway-pattern.html)\n\u003cbr\u003e\n\n## Data Transfer Object\n\nCan be used to transfer data between layers.\u003cbr\u003e\n[Martin Fowler Text about DTO](https://martinfowler.com/eaaCatalog/dataTransferObject.html)\n\n# Tests\n\nTests must follow the triple-A pattern (Arrange, Act, Assert).\n[Triple-A Article](https://medium.com/@pjbgf/title-testing-code-ocd-and-the-aaa-pattern-df453975ab80)\n\nExample:\n\n```dart\ntest('should execute a sum correctly', (){\n\n  // arrange\n  int number1 = 2;\n  int number2 = 1;\n\n  // act\n  final result = sumFunction(number1, number2);\n\n  // assert\n  expect(result, 3);\n\n});\n\n```\n\n\u003cbr\u003e\n\n## Test description\n\nThe test description should represent the expected result, according to the action performed.\nYou should _NOT_ use descriptions that are obvious like, for example, when a result of a list is expected to be a List you have to avoid a description as such: \"Should return a `List\u003cProduct\u003e` object\".\n\n\u003cbr\u003e\n\n## Test group\n\nThe groups must be named according to the class name, which may or may not be followed by the method.\nAt the end of the description, you must add \" | \" (space, pipe, space).\n\n\u003cbr\u003e\n\nStore example:\n\n```dart\ngroup('ProductStore | ', (){\n\n    // all ProductStore`s test\n\n});\n\n```\n\nRepository exemple:\n\n```dart\n\ngroup('ProductRepository.fetchAll | ', (){\n\n    // all ProductRepository.fetchAll`s test\n\n});\n```\n\n\u003cbr\u003e\n\u003cbr\u003e\n\n---\n\n\n# Tips\n\n## Modularize\n\nObviously we can keep our layers for the entire application but we can get more out of it by creating Interactor, Data and UI layers for each feature. Example:\n\n```\nmodule\n├── data\n│   ├── datasources\n│   └── repositories\n├── domain\n│   ├── entities\n│   └── usecases\n└── presenter\n    ├── stores\n    ├── controllers\n    ├── pages\n    └── widgets\n```\n\n## Think by layer\n\nWhen developing, start thinking by layer, we shouldn't worry about what's in the **UI** or **DATA** layer at the beginning of the functionality. If we think about the outermost layers, we can end up orienting ourselves (mistakenly) by these layers. Thus, we must get used to developing layer by layer, from the inside out and not the other way around.\n\nPerhaps at the beginning of your \"Clean\" journey some layers may seem \"useless\", this happens when our mind is not yet **Thinking in Layers** (or because your Business Rule is too simple for that).\n\n## Unit Testing will be your new UI\n\nIt is very common for developers to first create their Views so that they can then \"test\" the Business Rules. But we already have a proper tool for this and a dedicated place to store these tests.\n\nDeveloping in a \"clean\" way is in total synergy with TDD (Test Driven Development) as the UI layer will be one of the last things we will think about in the development of our feature.\n\n# Sign\n\nWe appreciate your feedback!\n\nIf you agree with the \"MiniCore Architecture\" proposal, leave a Star on this repository. A Star is the same as signing a \"clean manifesto\" agreeing with this proposal.\n\nWe are open to suggestions and improvements in documentation!\nDo this through the issues, our team will be very pleased with your interest in improving this tool for the community.\n\nFeel free to open a PR with corrections to the documentation of this proposal.\n\n# Examples\n\n- [Clean Dart Burgers Cart using BLoC, Cubit, Triple, Asp, MobX, etc](https://github.com/jacobaraujo7/bloc_atom)\n- Clean Dart Login with Firebase, MobX and Modular\n- [Clean Dart Github Search with BLoC and Modular](https://github.com/Flutterando/clean-dart-search-bloc)\n- [Clean Dart Github Search with MobX and Modular](https://github.com/jacobaraujo7/clean-dart-search-mobx)\n- [Simple App with MiniCore](https://github.com/viniciusddrft/mini_core_exemple)\n- [Todo App with MiniCore](https://github.com/EdsonMello-code/todoapp)\n\n# Links\n\n- [Resumo do livro \"Arquitetura Limpa\"](https://medium.com/@deividchari/desvendando-a-arquitetura-limpa-de-uncle-bob-3e60d9aa9cce)\n- [Sua Arquitetura está limpa?](https://medium.com/flutterando/sua-arquitetura-est%C3%A1-limpa-clean-architecture-no-flutter-458c68fad120)\n- [Os tijolos do Clean Architecture](https://www.youtube.com/watch?v=C8mpy3pwqQc)\n- [The Clean Code Blog](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Fminicore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflutterando%2Fminicore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflutterando%2Fminicore/lists"}