2021SC@SDUSC
一、基本构成介绍
Repository 模式:
App 开发中少不了对数据的操作,数据的来源可能有很多种:网络、数据库、文件以及内存中的缓存。而 Repository 就相当于一个仓库管理员,管理这些数据的存储。当业务层想要获取或者存储数据时,只需要通过 Repository 的管理员进行操作。这样的好处就是:屏蔽数据来源的操作接口。对于业务层来说不必关心数据存在哪里,以及如何存储的。而且也符合我们组件化/模块化架构设计的思想。即当我们更换数据存储设备时,例如从 Android 系统 Sqlite 数据转换为第三方的数据库时,不会影响到业务逻辑。
当前端需要调动后端执行一个动作时,前端ui将动作执行委托给viewmodel,viewmodel调用 respository中执行,在repository中根据情况选择从本地存储读取还是从网络读取,一般情况下优先选 择存储读取。repository应该是单例的,以免造成存在多个repository存在,造成本地数据库与网络数据 混淆,数据库数据不一致。
设计模式
?
二、datasource与repository
1.FriendAddDataSource
package com.example.minichatapp.data.friends;
import androidx.lifecycle.LiveData;
import com.example.minichatapp.data.Result;
import com.example.minichatapp.data.model.Friend;
import com.example.minichatapp.db.model.FriendRoom;
import java.util.List;
public class FriendRepository {
private static volatile FriendRepository instance;
private FriendDataSource dataSource;
public static FriendRepository getInstance(FriendDataSource dataSource) {
if(instance==null){
instance=new FriendRepository(dataSource);
}
return instance;
}
private FriendRepository(FriendDataSource dataSource){
this.dataSource=dataSource;
}
public Result<List<Friend>> getFriends(String uid){
return dataSource.getFriends(uid);
}
public LiveData<List<FriendRoom>> getFriendLiveData(){
return dataSource.getFriendsLiveData();
}
}
2. FriendAddRepository
package com.example.minichatapp.data.friends;
import android.os.AsyncTask;
import com.example.minichatapp.App;
import com.example.minichatapp.data.Result;
import com.example.minichatapp.data.model.Friend;
import com.example.minichatapp.db.APPDataBase;
import com.example.minichatapp.db.model.FriendRoom;
public class FriendAddRepository {
private static volatile FriendAddRepository instance;
private FriendAddDataSource dataSource;
public static FriendAddRepository getInstance(FriendAddDataSource source) {
if(instance==null){
instance=new FriendAddRepository(source);
}
return instance;
}
public FriendAddRepository(FriendAddDataSource dataSource) {
this.dataSource = dataSource;
}
public void setFriend(Friend friend){
//load into local storage
FriendRoom friendRoom=new FriendRoom(friend.getFid(),friend.getUid(),friend.getF_name(),friend.getNick_name());
AsyncTask.execute(new Runnable() {
@Override
public void run() {
APPDataBase db= App.getInstance().getDataBase();
db.friendDao().insertFriendOne(friendRoom).blockingSubscribe();
}
});
}
public Result<Friend> addFriend(String uid,String f_id){
Result<Friend> friendResult=dataSource.addFriend(uid,f_id);
if(friendResult instanceof Result.Success){
setFriend(((Result.Success<Friend>) friendResult).getData());
}
return friendResult;
}
}
3.FriendDataSource
package com.example.minichatapp.data.friends;
import android.os.AsyncTask;
import android.util.Log;
import androidx.lifecycle.LiveData;
import com.example.minichatapp.App;
import com.example.minichatapp.NetService.Base.HpException;
import com.example.minichatapp.NetService.HpImpl.friend.FriendHpImpl;
import com.example.minichatapp.NetService.HpModel.Response.FriendResponse;
import com.example.minichatapp.data.Result;
import com.example.minichatapp.data.model.Friend;
import com.example.minichatapp.db.dao.FriendDao;
import com.example.minichatapp.db.model.FriendRoom;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class FriendDataSource {
private LiveData<List<FriendRoom>> friendsLiveData;
private final FriendDao dao;
public FriendDataSource() {
dao= App.getInstance().getDataBase().friendDao();
//friendsLiveData=dao.getFriendsByUId(uid);
}
public Result<List<Friend>> getFriends(String uid){
List<Friend> friendList=new ArrayList<>();
//if (friendsLiveData==null||friendsLiveData.getValue()==null){
List<FriendRoom> friendRoomList=new ArrayList<>();
//remote
try{
List<FriendResponse> responseList=new FriendHpImpl().getFriendsById(uid);
for(FriendResponse response:responseList){
if (response.getCode()>0){
friendList.add(new Friend(response.getFid(),response.getUid(),response.getF_name(),response.getNick_name()));
friendRoomList.add(new FriendRoom(response.getFid(),response.getUid(),response.getF_name(),response.getNick_name()));
}else {
return new Result.Error(new IOException("Error fetching friends"));
}
}
//load into room
AsyncTask.execute(new Runnable() {
@Override
public void run() {
if(friendRoomList.size()>0){
dao.insertFriends(friendRoomList).blockingSubscribe();
friendsLiveData=dao.getFriendsByUId(uid);
}
}
});
}catch (HpException hp){
return new Result.Error(new Exception("NetService was shut down."));
}
for (Friend f:friendList
) {
Log.d("friendListItme",f.toString());
}
// }else {
// //room
// List<FriendRoom> friendRoomList=friendsLiveData.getValue();
// for (FriendRoom friendRoom:friendRoomList){
// friendList.add(new Friend(friendRoom.fid,friendRoom.uid,friendRoom.f_name,friendRoom.nick_name));
// }
// }
return new Result.Success<>(friendList);
}
public LiveData<List<FriendRoom>> getFriendsLiveData() {
return friendsLiveData;
}
}
4.FriendRepository
package com.example.minichatapp.data.friends;
import androidx.lifecycle.LiveData;
import com.example.minichatapp.data.Result;
import com.example.minichatapp.data.model.Friend;
import com.example.minichatapp.db.model.FriendRoom;
import java.util.List;
public class FriendRepository {
private static volatile FriendRepository instance;
private FriendDataSource dataSource;
public static FriendRepository getInstance(FriendDataSource dataSource) {
if(instance==null){
instance=new FriendRepository(dataSource);
}
return instance;
}
private FriendRepository(FriendDataSource dataSource){
this.dataSource=dataSource;
}
public Result<List<Friend>> getFriends(String uid){
return dataSource.getFriends(uid);
}
public LiveData<List<FriendRoom>> getFriendLiveData(){
return dataSource.getFriendsLiveData();
}
}
(二)个人主页
1.Homedatasource?
package com.example.minichatapp.data.home;
import com.example.minichatapp.App;
import com.example.minichatapp.data.Result;
import com.example.minichatapp.data.model.User;
import com.example.minichatapp.db.APPDataBase;
import com.example.minichatapp.db.model.UserRoom;
import java.io.IOException;
import io.reactivex.rxjava3.core.Single;
public class HomeDataSource {
public Result<User> getUser(){
//访问数据库,并返回信息
APPDataBase appDataBase= App.getInstance().getDataBase();
Single<UserRoom> userSingle=appDataBase.userDao().getLogUser();
try{
UserRoom u=userSingle.blockingGet();
User user=new User(u.uid,u.userName);
return new Result.Success<>(user);
}catch (NullPointerException e){
return new Result.Error(new IOException("Error getUser in",e));
}
}
}
?2.Homerepository
package com.example.minichatapp.data.home;
import com.example.minichatapp.data.Result;
import com.example.minichatapp.data.model.User;
public class HomeRepository {
private static volatile HomeRepository instance;
private HomeDataSource dataSource;
private HomeRepository(HomeDataSource dataSource)
{
this.dataSource=dataSource;
}
public static HomeRepository getInstance(HomeDataSource dataSource){
if(instance==null){
instance=new HomeRepository(dataSource);
}
return instance;
}
public Result<User> getUser(){
Result<User> user=dataSource.getUser();
return user;
}
}
(三)登录
1. Logindatasource
package com.example.minichatapp.data.login;
import com.example.minichatapp.NetService.HpImpl.login.LoginHpImpl;
import com.example.minichatapp.NetService.HpModel.Response.LoginResponse;
import com.example.minichatapp.data.Result;
import com.example.minichatapp.data.model.LoggedInUser;
import java.io.IOException;
public class LoginDataSource {
public Result<LoggedInUser> login(String uid, String password) {
try {
// 网络登录操作
LoginResponse response=new LoginHpImpl().login(uid,password);
LoggedInUser user=null;
if(response.getCode()>0){
user =
new LoggedInUser(true,
uid,response.getName(),response.getToken()
);
}else {
user =
new LoggedInUser(false,
null,null,null
);
}
return new Result.Success<>(user);
} catch (Exception e) {
return new Result.Error(new IOException("Error logging in", e));
}
}
}
2.Loginrespository
package com.example.minichatapp.data.login;
import android.os.AsyncTask;
import android.util.Log;
import com.example.minichatapp.App;
import com.example.minichatapp.data.Result;
import com.example.minichatapp.data.model.LoggedInUser;
import com.example.minichatapp.db.APPDataBase;
import com.example.minichatapp.db.model.UserRoom;
public class LoginRepository {
private static volatile LoginRepository instance;
private LoginDataSource dataSource;
// If user credentials will be cached in local storage, it is recommended it be encrypted
private LoggedInUser user = null;
// private constructor : singleton access
private LoginRepository(LoginDataSource dataSource) {
this.dataSource = dataSource;
}
public static LoginRepository getInstance(LoginDataSource dataSource) {
if (instance == null) {
instance = new LoginRepository(dataSource);
}
return instance;
}
public boolean isLoggedIn() {
return user != null;
}
private void setLoggedInUser(LoggedInUser user) {
this.user = user;
UserRoom u=new UserRoom();
u.uid=user.getUserId();
u.userName=user.getDisplayName();
u.isLog=1;
APPDataBase db=App.getInstance().getDataBase();
//先修改isLog=true用于切换账号
AsyncTask.execute(new Runnable() {
@Override
public void run() {
db.userDao().updateLog().blockingSubscribe();
db.userDao().delete(u.uid).blockingSubscribe();
Log.d("userRoomLogin",u.toString());
db.userDao().insertOne(u).blockingSubscribe();
}
});
}
public Result<LoggedInUser> login(String username, String password) {
// handle login
Result<LoggedInUser> result = dataSource.login(username, password);
if (result instanceof Result.Success) {
LoggedInUser loggedInUser=((Result.Success<LoggedInUser>) result).getData();
if(loggedInUser.isOk()){
setLoggedInUser(loggedInUser);
}
}
return result;
}
}
|