flutterclean-architecture

Approach to Handling Plugin and Package Dependencies in Clean Architecture Data Sources?


I'm exploring clean architecture and have noticed in many articles and videos that they pass packages/plugins to the data source. For instance, using SharedPreferences for the local data source and http for the remote data source. So, I have a few questions:

  1. What if we need to replace SharedPreferences and HTTP with other plugins and packages in the future? Would we have to refactor all the data sources?
  2. Is there any reason why we should not wrap these packages in a wrapper class to make them reusable? for example if we use http.client with specifc headers then lot of same code to write in every datasource classes.
  3. Is there any way we can change plugins and packages used in the data source without touching existing logic and data mapping in datasource class? Because if we change packages, then return type of data might also change, requiring us to refactor accordingly.

Could you provide suggestions on how to tackle this problem?

Example - datasource class using http.client

class NumberTriviaRemoteDataSourceImpl implements NumberTriviaRemoteDataSource {
  final http.Client client; 

  NumberTriviaRemoteDataSourceImpl({@required this.client});


  Future<NumberTriviaModel> _getTriviaFromUrl(String url) async {
    final response = await client.get(
      url,
      headers: {
        'Content-Type': 'application/json',
      },
    );

    if (response.statusCode == 200) {
      return NumberTriviaModel.fromJson(json.decode(response.body));
    } else {
      throw ServerException();
    }
  }
}

Solution

    1. Recommended way to deal with this is using Abstraction. High-level modules should not depend on low-level modules. Both should depend on abstractions. So if you need to change packages/plugins later, you only need to create new implementations of these abstract classes without touching the existing logic in your data source classes.

    2. Using the above concept, if you're using HTTP with specific headers across multiple data sources, creating a wrapper class can centralize the logic for headers and simplify your data source classes.

    3. Study Dependency Injection, you can easily swap them out without modifying the existing logic.

    Here's an example