Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Architecture with several data sources using Repository pattern

I have a project using MVP architecture. This project use the Repository pattern.

I have two data sources, the first one come from a remote JSON Api through PollutionApiService, the second is just trivial data I get from an XML file in the assets folder : air_quality_levels.xml. The network data contains real time pollution levels, the XML file contains the limits standard for these pollution levels.

For now I just have a Repository implemented for the JSON Api, it looks like this :

Interface

public interface Repository {
    Observable<Aqicn> getPollutionLevelsFromNetwork(String city, String authToken);
   Observable<Aqicn> getPollutionLevels(String city, String authToken);
}

Class

public class PollutionLevelsRepository implements Repository {
    private PollutionApiService pollutionApiService;
    private static Observable<Aqicn> pollutionData = null;


    public PollutionLevelsRepository(PollutionApiService pollutionApiService) {
        this.pollutionApiService = pollutionApiService;
    }

    @Override
    public Observable<Aqicn> getPollutionLevelsFromNetwork(String city, String authToken) {
        pollutionData = pollutionApiService.getPollutionObservable(city, authToken);
        return pollutionData;
    }

    @Override
    public Observable<Aqicn> getPollutionLevels(String city, String authToken) {
        return getPollutionLevelsFromNetwork(city, authToken);
    }
}

Should I use the same repository (adding more methods) for the data I will get from the XML file in the assets folder ?

If I have to use two repositories, How should I name this second repository interface ? I never had several repositories so I always use the generic name "Repository" for the interface. I can't give it the same name as the class and can't add a "I" prefix as I read it's bad practice... Or should I keep this "Repository" name and put the new Repository in another package ?

This is my actual project structure, note that I package by features but I put my both repositories in the common package because it gets data that will be used by my both features (donut and pollutionlevels) :

enter image description here

If you have short relevant suggestions about the architecture in general they are welcome.

like image 519
Laurent Avatar asked Apr 29 '17 01:04

Laurent


People also ask

Is repository pattern a architecture?

Architecture plays a crucial role in any software development process. If you want to build a more robust, reusable, testable, and re-configurable system, you have to invest heavily in designing the architecture.

What is the benefit of repository pattern useful for 3 tier architecture?

Benefits of Repository PatternIt centralizes data logic or business logic and service logic. It gives a substitution point for the unit tests. Provides a flexible architecture. If you want to modify the data access logic or business access logic, you don't need to change the repository logic.

What is repository pattern in MVVM?

In using the Repository design pattern, you can hide the details of how the data is eventually stored or retrieved to and from the data store. This data store can be a database, an xml file, etc.

What is a repository in software architecture?

The Architecture Repository is a software tool that stores the important architectural input and output, including Architectures themselves, the elements of which they are composed, standards, references, principles and the Governance Register.


1 Answers

The idea of a Repository is to act as an abstraction between where the data is actually coming from and the business logic code which consumes it. Your business logic should neither know or care whether data is coming via the network, xml or from anywhere else. This allows flexibility in future so that you are free to make changes to the implementation of fetching the data (caching, offline storage, etc) whilst still maintaining the original contract of the Repository.

I tend to create a separate Repository for each 'type' of data. In your case both the network request and the xml are pollution level data so I would put them in the same Repository. If however you needed to have user data then I would make a separate class to deal with this (AccountRepositoy possibly).

With the above in mind I would create a class PollutionLevelsRepository as follows:

public class PollutionLevelsRepository {

    private PollutionHttp pollutionHttp;
    private PollutionXml pollutionXml;

    public PollutionLevelsRepository(PollutionHttp pollutionHttp, PollutionXml pollutionXml) {
        this.pollutionHttp = pollutionHttp;
        this.pollutionXml = pollutionXml;
    }

    public Observable<Aqicn> getRealTimePollutionLevels(String city) {

        // currently this method runs the http request
        // note that I have removed the auth token - this is a network
        // implementation detail and probably shouldn't be part of the public api
        return pollutionHttp.getPollutionLevels(city);
    }

    public Observable<Aqicn> getPollutionLimitStandard(String city) {

        // this method would return data from the xml
        return pollutionXml.getPollutionLimit(city);
    }
}

Note that the method names give no indication of where the data is coming from. You are free to change this at any time. Also I see no reason to implement an interface. Others might disagree with this but as you're only going to have one implementation I would call YAGNI and say that it just introduces unnecessary complexity.

The two classes PollutionHttp & PollutionXml are your model classes responsible for actually doing the http request and parsing the data from xml (call them what you want!)

like image 117
Jahnold Avatar answered Sep 28 '22 01:09

Jahnold