{"id":13553934,"url":"https://github.com/ckdevrel/solid-principles-flutter","last_synced_at":"2026-01-28T07:20:37.546Z","repository":{"id":138404908,"uuid":"228946016","full_name":"ckdevrel/solid-principles-flutter","owner":"ckdevrel","description":null,"archived":false,"fork":false,"pushed_at":"2019-12-19T03:28:43.000Z","size":20,"stargazers_count":15,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-04T01:32:59.420Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://takeoffandroid.github.io/solid-principles-flutter","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ckdevrel.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}},"created_at":"2019-12-19T00:46:20.000Z","updated_at":"2023-03-23T17:03:49.000Z","dependencies_parsed_at":"2024-01-01T05:30:47.427Z","dependency_job_id":"fd5b7730-7f81-4092-a52c-18992199230b","html_url":"https://github.com/ckdevrel/solid-principles-flutter","commit_stats":null,"previous_names":["ckdevrel/solid-principles-flutter"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckdevrel%2Fsolid-principles-flutter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckdevrel%2Fsolid-principles-flutter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckdevrel%2Fsolid-principles-flutter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ckdevrel%2Fsolid-principles-flutter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ckdevrel","download_url":"https://codeload.github.com/ckdevrel/solid-principles-flutter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246944379,"owners_count":20858773,"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-08-01T12:02:36.292Z","updated_at":"2026-01-28T07:20:37.541Z","avatar_url":"https://github.com/ckdevrel.png","language":null,"readme":"# Flutter Solid Principles\n\n## S — The Single Responsibility Principle (SRP):\n\n### Bad\n\n```dart\n @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: new Scaffold(\n          body: FutureBuilder(\n              future: getFeedsFromApi(),\n              builder: (context,  snapshot) {\n                  switch(snapshot.connectionState){\n                    case ConnectionState.waiting:\n                      return EmptySpendsPage();\n                    case ConnectionState.none:\n                      return EmptySpendsPage();\n                    case ConnectionState.active:\n                      return EmptySpendsPage();\n                    case ConnectionState.done:\n                      return ListView.builder(\n                          itemCount: snapshot.data == null ? 0 : snapshot.data.length,\n                          itemBuilder: (context, position) {\n                            FeedItem feedItem = snapshot.data[position];\n                            return null;\n                          });\n                  }\n\n              }\n          )\n      ),\n    );\n  }\n```\n\n### Good\n\n```dart\n @override\n  Widget build(BuildContext context) {\n    bloc.add(NoParams());\n    return Scaffold(\n      body: BlocBuilder\u003cFeedsBloc, FeedsState\u003e(\n          bloc: bloc,\n          builder: (BuildContext context, FeedsState feedState) {\n            if (feedState is FeedsLoading) {\n              return Center(child: CircularProgressIndicator());\n            } else if (feedState is FeedsError) {\n              return Text('Ayo! Error');\n            } else if (feedState is FeedsLoaded) {\n              return FeedList(feeds: feedState.feedItems);\n            }\n            return Container(\n                color: Colors.orangeAccent,\n                height: double.infinity,\n                width: double.infinity);\n          }),\n    );\n  }\n```\n## O — The Open-Closed Principle (OCP)\n\n### Bad\n\n```dart\nvoid main() {\n    MileageCalculator mileageCalculator = new MileageCalculator();\n    mileageCalculator.showMileage(new Bike());\n}\n\nclass MileageCalculator {\n    void showMileage(dynamic anyVehicle) {\n      if(anyVehicle is Bike) {\n          print(anyVehicle.getBikeMileage());\n      } else if(anyVehicle is Car) {\n          print(anyVehicle.getCarMileage());\n      }\n    }\n}\n\nclass Bike {\n    String getBikeMileage() =\u003e \"50\";\n}\n\nclass Car {\n    String getCarMileage() =\u003e \"12\";\n}\n```\n\n### Good\n\n```dart\nvoid main() {\n    MileageCalculator mileageCalculator = new MileageCalculator();\n    mileageCalculator.showMileage(new Car());\n}\n\nclass MileageCalculator {\n    void showMileage(Vehicle vehicle) {\n       print(vehicle.getMileage());\n    }\n}\n\nclass Bike extends Vehicle {\n    String getMileage() =\u003e \"50\";\n}\n\nclass Car extends Vehicle {\n    String getMileage() =\u003e \"12\";\n}\n\nabstract class Vehicle {\n  String getMileage();\n}\n```\n\n## L - The Liskov Substitution Principle (LSP)\n\n### Bad\n\n```dart\nvoid main() {\n    StatelessWidget adapter = new StatelessWidget();\n    adapter.select(new RadioButtonWidget());\n}\n\nclass StatelessWidget {\n    void select(ClickListener clickListener) {\n        if (clickListener is ListItemWidget) { \n            clickListener.changeTheBackground();\n        } else if (clickListener is RadioButtonWidget) {\n            clickListener.check();\n        }\n        clickListener.onClick(1);\n    }\n}\n\nmixin ClickListener {\n    void onClick(int position);\n} \n\nclass ListItemWidget implements ClickListener {\n    @override \n    void onClick(int position){\n       print(\"Clicked list item $position\");\n    }\n    \n    void changeTheBackground() {\n       print(\"Change the background color of the item view\");\n    }\n    \n}\n\nclass RadioButtonWidget implements ClickListener {\n    @override \n    void onClick(int position){\n       print(\"Clicked radio button $position\");\n    }\n    \n    void check() {\n       print(\"Enable the radio button\");\n    }\n}\n```\n\n### Good\n\n```dart\nvoid main() {\n    StatelessWidget adapter = new StatelessWidget();\n    adapter.select(new RadioButtonWidget());\n}\n\nclass StatelessWidget {\n    void select(ClickListener clickListener) {\n        clickListener.onClick(1);\n    }\n}\n\nmixin ClickListener {\n    void onClick(int position);\n} \n\nclass ListItemWidget implements ClickListener {\n    @override \n    void onClick(int position){\n        print(\"Clicked list item $position\");\n       _changeTheBackground();\n    }\n    \n    void _changeTheBackground() {\n       print(\"Change the background color of the item view\");\n    }\n}\n\nclass RadioButtonWidget implements ClickListener {\n    @override \n    void onClick(int position){\n       print(\"Clicked radio button $position\");\n      _check();\n    }\n    \n    void _check() {\n       print(\"Enable the radio button\");\n    }\n}\n```\n## I — The Interface Segregation Principle (ISP):\n\n### Bad\n\n```dart \nclass ImageViewWidget with OnClickListener {\n   @override \n   void onImageClick(int position) {\n        // Yes, I have received a callback, go to the next activity.\n        print(\"Clicked position is $position\");\n   }\n   @override \n   void onRadioButtonClick(int position) {\n        // This is no longer needed for this activity, but still I have been implemented for no use...\n   }\n}\n\n mixin OnClickListener {\n    void onImageClick(int position);\n    void onRadioButtonClick(int position);\n }\n```\n\n### Good\n\n```dart\nclass ImageViewWidget with OnImageClickListener {\n   @override \n   void onImageClick(int position) {\n        // Yes, I have received a callback, go to the next activity.\n        print(\"Clicked position is $position\");\n   }\n}\n\n mixin OnImageClickListener {\n    void onImageClick(int position);\n }\n \n mixin OnRadioButtonClickListener {\n    void onRadioButtonClick(int position);\n }\n```\n\n## D - The Dependency Inversion Principle (DIP)\n\n### Bad\n```dart\n\nclass RepositoryImpl {\n  List\u003cFeedItem\u003e getDataFromApi() {\n    // do your api call\n  }\n  \n  List\u003cFeedItem\u003e getDataFromCache() {\n    // get the data from the database\n  }\n}\n```\n\n### Good\n```dart\nclass RepositoryImpl {\n  \n  RemoteDataSource remoteDataSource;\n  LocalDataSource locaDataSource;\n  \n  RepositoryImpl(this.remoteDataSource, this.locaDataSource);\n}\n\nabstract class RemoteDataSource {\n  List\u003cFeedItem\u003e getDataFromApi();\n}\n\nabstract class LocalDataSource {\n  List\u003cFeedItem\u003e getDataFromCache();\n}\n\nclass RemoteDataSourceImpl extends RemoteDataSource{\n  // Lets assume this class has an access to http client\n  List\u003cFeedItem\u003e getDataFromApi(){\n        // do your api call\n  }\n}\n\nclass LocalDataSourceImpl extends LocalDataSource {\n    // Lets assume this class has an access to database instance\n  List\u003cFeedItem\u003e getDataFromCache(){\n        // get the data from the database\n  }\n}\n```\n","funding_links":[],"categories":["Others"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckdevrel%2Fsolid-principles-flutter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fckdevrel%2Fsolid-principles-flutter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fckdevrel%2Fsolid-principles-flutter/lists"}