What is Repository mode
Repository This word literal translation come over warehouse, warehousing meaning. This meaning can also reflect the role of Repository mode. There are many possible sources of data in APP development: networks, databases, files, and in-memory caches. And Repository is the equivalent of a warehouse administrator to manage the storage of this data. When the business layer wants to acquire or store data, it only needs to be operated by the Repository administrator. The advantage is that the interface of the data source is shielded. for the business layer, there is no need to worry about where the data exists and how it is stored. It also conforms to our idea of modular/modularized architecture design. that is, when we replace a data storage device, such as from the Android system Sqlite data to a third-party database, the business logic is not affected.
Design Patterns
First, preview the design class diagram of the Repository mode (Welcome to shoot Bricks)
IDataSource
is to define the data source interface, which is defined according to the specific business needs. Generally speaking, there are several ways to increase, delete, change and check these.
LocalRepository
The encapsulation is the local storage method, implements the IDataSource
interface.
RemoteRepository
The encapsulation is the network storage way, implements the IDataSource
interface.
LocalRepository
and RemoteRepository
that represents the specific implementation of various storage methods. The RepositoryFactory
legendary "warehouse manager", which manages various storage methods, is also a bridge between the business layer and the data tier .
Show me the Code
Suppose that there is a business that is required to obtain remote data, and if locally cached data is obtained locally, it is obtained from the network. Such business logic is common, and we use Repository
Mode for encapsulation.
Preview your code's overall structure first
IDataSource
Public Interface Idatasource<t> { void Add (t t); void Delete (T t); void Update (T t); List<T> queryall (); T Querybyid (int ID);}
Localrepository
Public classLocalrepositoryImplementsIdatasource<data> { Publiclocalrepository () {} @Override Public voidAdd (data data) {Dbhelper.get (). Add (data); } @Override Public voidDelete (data data) {Dbhelper.get (). Delete (data); } @Override Public voidUpdate (data data) {Dbhelper.get (). Update (data); } @Override PublicList<data>Queryall () {returndbhelper.get (). Queryall (); } @Override PublicData Querybyid (intID) {returndbhelper.get (). Querybyid (ID); }}
Remoterepository
Public classRemoterepositoryImplementsIdatasource<data>{@Override Public voidAdd (data data) {Dataapi.get (). Add (data); } @Override Public voidDelete (data data) {Dataapi.get (). Delete (data); } @Override Public voidUpdate (data data) {Dataapi.get (). Update (data); } @Override PublicList<data>Queryall () {returndataapi.get (). Queryall (); } @Override PublicData Querybyid (intID) {returndataapi.get (). Querybyid (ID); }}
Repositoryfactory
Public classRepositoryfactoryImplementsIdatasource<data> { PrivateIdatasource<data>Local; PrivateIdatasource<data>remote; Private Staticrepositoryfactory INSTANCE; /*** Use map to implement a memory cache*/HashMap<string, data> Mcache =NewHashmap<>(); PrivateRepositoryfactory (@NonNull idatasource<data> Local, @NonNull idatasource<data>remote) { This. local =Local; This. Remote =remote; } Public StaticRepositoryfactory get (@NonNull idatasource<data> Local, @NonNull idatasource<data>remote) { if(INSTANCE = =NULL) {INSTANCE=Newrepositoryfactory (local, remote); } returnINSTANCE; } Public StaticRepositoryfactory Get () {if(INSTANCE = =NULL) {INSTANCE=NewRepositoryfactory (NewLocalrepository (),Newremoterepository ()); } returnINSTANCE; } Public voiddestory () {INSTANCE=NULL; } @Override Public voidAdd (data data) {Local.add (data); Remote.add (data); Mcache.put (String.valueof (data.id), data); } @Override Public voidDelete (data data) {Local.delete (data); Remote.delete (data); Mcache.remove (string.valueof (data.id)); } @Override Public voidUpdate (data data) {local.update (data); Remote.update (data); Mcache.put (String.valueof (data.id), data); } /** * @return */@Override PublicList<data>Queryall () {List<Data> list =Local.queryall (); if(List.isEmpty ()) {list=Remote.queryall (); } returnlist; } /*** This uses a level three cache to get a data object * *@paramID *@return */@Override PublicData Querybyid (intID) {Data data=Mcache.get (string.valueof (id)); if(Data = =NULL) {Data=Local.querybyid (ID); } if(Data = =NULL) {Data=Remote.querybyid (ID); } if(Data! =NULL) {Mcache.put (string.valueof (ID), data); } returndata; }}
Using the example
Flowable.fromcallable (NewCallable<list<data>>() {@Override PublicList<data> Call ()throwsException {List<Data> dataList =repositoryfactory.get (). Queryall (); returndataList; }}). Observeon (Androidschedulers.mainthread ()). Subscribeon (Schedulers.io ()). Subscri Be (NewConsumer<list<data>>() {@Override Public voidAccept (@NonNull list<data> datas)throwsException {textview.settext ("Data size:" +datas.size ()); } }, NewConsumer<throwable>() {@Override Public voidAccept (@NonNull throwable throwable)throwsException {textview.settext (Throwable.getmessage ()); } });
Here is the direct use of RXJAVA2 to call, because Repository is the data request and access, this is a time-consuming operation, it needs to be placed in the background thread. MVP is typically used to encapsulate this layer in actual projects.
This article demo:wecodexyz/componentization
Reference: Googlesamples/android-architecture
APP component/Modular path--repository mode