模型层(MVP)应该使用 Activity 引用
The model layer (MVP) should use the Activity reference
当模型中有一个操作需要当前 activity 实例时,如何在模型层和视图层之间进行适当的分离?
例如,我在我的 Android 应用程序中集成了 Linkedin SDK(用 MVP 编写)。
在 auth 过程中,当 init() 方法的第一个参数类型为 Activity:
时,我有以下代码片段
public void authWithLinkedin(final IAuth listener, Activity activity) {
LISessionManager.getInstance(MyApplication.getContext()).init(activity, buildScope(), new AuthListener() {
@Override
public void onAuthSuccess() {
listener.onSuccess();
}
@Override
public void onAuthError(LIAuthError error) {
listener.onError();
}
}, true);
}
如果我的模型层应该了解 Android 框架组件,我还有哪些选择可以保持 MVP 架构的清洁?
您可以使用像
这样的软件约定/原则
"dependency inversion principle"
你的模型层应该不知道Android如果你能避免它是重点。
尝试这样的事情:
型号:
private final SocialLoginProvider socialLoginProvider;
public MyModel(SocialLoginProvider socialLoginProvider) {
this.socialLoginProvider = socialLoginProvider;
}
public void authWithLinkedin(final IAuth listener) {
socialLoginProvider.init(buildScope(), new SocialLoginProvider.Listener() {
@Override
public void onAuthSuccess() {
listener.onSuccess();
}
@Override
public void onAuthError() {
listener.onError();
}
}, true);
}
工厂:
public MyModel getModel(Context context) {
LISessionManager li = LISessionManager.getInstance(context);
SocialLoginProvider provider = new LinkedInSocialLoginProvider(context, li);
return new MyModel(provider);
}
接口:
public interface SocialLoginProvider {
void init(Scope scope, Listener listener);
interface Listener {
void onAuthSuccess();
void onAuthError();
}
}
SocialLoginProvider 的适配器:
public class LinkedInSocialLoginProvider implements SocialLoginProvider {
private final Context context;
private final LISessionManager linkedInSessionManager;
public LinkedInSocialLoginProvider(Context context, LISessionManager linkedInSessionManager) {
this.context = context;
this.linkedInSessionManager = linkedInSessionManager;
}
@Override
public void init(Scope scope, Listener listener) {
linkedInSessionManager.init(context, scope,
new AuthListener() {
@Override
public void onAuthSuccess() {
listener.onSuccess();
}
@Override
public void onAuthError(LIAuthError error) {
listener.onError();
}
}, true);
}
}
理想情况下,模型层中有 Android 个框架组件是可以的。例如,您将需要 Context
到 store/access 本地数据,使用 getDefaultSharedPreferences(Context)
and/or 使用 SQLiteOpenHelper
管理本地数据库。
LISessionManager.getInstance(MyApplication.getContext()).init
看起来像 BroadcastReceiver
,因为它是一种从外部组件接收特定结果的侦听器。处理这种情况可以参考this
当模型中有一个操作需要当前 activity 实例时,如何在模型层和视图层之间进行适当的分离?
例如,我在我的 Android 应用程序中集成了 Linkedin SDK(用 MVP 编写)。 在 auth 过程中,当 init() 方法的第一个参数类型为 Activity:
时,我有以下代码片段public void authWithLinkedin(final IAuth listener, Activity activity) {
LISessionManager.getInstance(MyApplication.getContext()).init(activity, buildScope(), new AuthListener() {
@Override
public void onAuthSuccess() {
listener.onSuccess();
}
@Override
public void onAuthError(LIAuthError error) {
listener.onError();
}
}, true);
}
如果我的模型层应该了解 Android 框架组件,我还有哪些选择可以保持 MVP 架构的清洁?
您可以使用像
这样的软件约定/原则"dependency inversion principle"
你的模型层应该不知道Android如果你能避免它是重点。
尝试这样的事情:
型号:
private final SocialLoginProvider socialLoginProvider;
public MyModel(SocialLoginProvider socialLoginProvider) {
this.socialLoginProvider = socialLoginProvider;
}
public void authWithLinkedin(final IAuth listener) {
socialLoginProvider.init(buildScope(), new SocialLoginProvider.Listener() {
@Override
public void onAuthSuccess() {
listener.onSuccess();
}
@Override
public void onAuthError() {
listener.onError();
}
}, true);
}
工厂:
public MyModel getModel(Context context) {
LISessionManager li = LISessionManager.getInstance(context);
SocialLoginProvider provider = new LinkedInSocialLoginProvider(context, li);
return new MyModel(provider);
}
接口:
public interface SocialLoginProvider {
void init(Scope scope, Listener listener);
interface Listener {
void onAuthSuccess();
void onAuthError();
}
}
SocialLoginProvider 的适配器:
public class LinkedInSocialLoginProvider implements SocialLoginProvider {
private final Context context;
private final LISessionManager linkedInSessionManager;
public LinkedInSocialLoginProvider(Context context, LISessionManager linkedInSessionManager) {
this.context = context;
this.linkedInSessionManager = linkedInSessionManager;
}
@Override
public void init(Scope scope, Listener listener) {
linkedInSessionManager.init(context, scope,
new AuthListener() {
@Override
public void onAuthSuccess() {
listener.onSuccess();
}
@Override
public void onAuthError(LIAuthError error) {
listener.onError();
}
}, true);
}
}
理想情况下,模型层中有 Android 个框架组件是可以的。例如,您将需要 Context
到 store/access 本地数据,使用 getDefaultSharedPreferences(Context)
and/or 使用 SQLiteOpenHelper
管理本地数据库。
LISessionManager.getInstance(MyApplication.getContext()).init
看起来像 BroadcastReceiver
,因为它是一种从外部组件接收特定结果的侦听器。处理这种情况可以参考this