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) :
If you have short relevant suggestions about the architecture in general they are welcome.
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.
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.
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.
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.
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!)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With