在我的Android应用中,我有一个MVP模式的片段。假设我们有:
我需要进行多步计算或REST调用:
val sessionId = presenter.firstCall() as String
来检索sessionToken以作进一步处理。NfcAdapter.getDefaultAdapter(activity)
。 val jsonObject = secondCall(sessionId, nfcAdapter)
。
由于我在演示者中,所以我既没有活动也没有NfcAdapter(老实说,我不想这样做)。我在这里有两个选择:
view?.onFirstCallResult(sessionToken)
的片段,并立即从CalculationFragment的onFirstCallResult()
调用presenter.secondCall(sessionToken, NfcAdapter.getDefaultAdapter(activity))
。什么是优雅的解决方案/模式?
答案 0 :(得分:0)
向 Presenter ,模型或命令添加更多逻辑,从而将其从视图中删除。这通常是一种更好的方法。考虑到Single Responsibility principle,并从视图中移动应用程序/域逻辑。
您可以通过以下两种方式执行此操作:
使用Command。 演示者将创建并调用。 命令完成后,演示者会将结果返回到视图。
设计您的演示者,以像在第二张图中一样完成工作。如果演示者很简单就可以。对于更复杂的场景,使用命令将执行逻辑的职责与应在何时调用的职责分开。
< / li>根据您的情况,您需要从视图获取 NfcAdapter 到 Presenter 和 Command (如果你有一个)。
您可以通过以下几种方式进行操作:
public void initialize(NfcAdapter adapter, ...)
)NfcAdapter view.getAdapter()
)。选择一种方法取决于几个因素,开发人员的口味便是其中之一。就我个人而言,我会选择方法1或2。我想初始化对象的依赖关系(在这种情况下,是 Presenter )在生命周期的乞讨中,如果始终需要此对象,并且它们不会改变。如果每次调用此方法时它们都发生变化,则将它们传递给方法调用。在这种情况下,我认为您不会更改 NfcAdapter 。
让我们设计一个命令。因为您的描述比较笼统,而且没有描述确切的顺序(first_call(),second_call()太笼统),所以我将设计一个简单的非特定系统来进行几次调用。我将使用伪代码。大多数事情都是不确定的,因为我不知道返回类型和东西。
我们将此命令称为 CalculateCommand 。此命令将使用 CalculationModel 进行计算。接下来,让我们定义一个 TokenService ,其中将包含获取令牌(API调用)的逻辑。
public class TokenService {
public SessionToken getToken() { ... }
}
public class CalculationResult {
// represent whatever the result is...
}
public class CalculateCommand {
private NfcAdapter mNfcAdapter;
private TokenService mTokenService;
private CalculationModel mCalculationModel;
private SessionToken mSessionToken;
public CalculateCommand(
NfcAdapter nfcAdapter,
TokenService tokenService,
CalculationModel calculationModel) {
mAdapter = adapter;
mTokenService = tokenService;
mCalculationModel = calculatioModel;
}
public CalculationResult Execute() {
startSession();
// do more stuff if you need to
val result = calculate();
return result;
}
private void startSession() {
mSessionToken = mTokenService.getToken();
}
private Result calcualte() {
//not sure what parameters it needs but pass them here
return mCalculatioModel.calculate(params...);
}
}
public class Presenter {
private View mView;
private NfdAdapter mAdapter;
private CalculationModel mModel;
private TokenService mTokenService;
public Presenter(View view, NfdAdapter adapter) {
mView = view;
mNfcAdapter = adapter;
mModel = new CalculationModel();
// or get if from a Service Locator, DI whatever.. if you need to mock the
// TokenService for unittests
mTokenService = new TokenService();
}
public void performCalculation() {
val cmd = CalculationCommand(mAdapter, mTokenService, mModel);
val result = cmd.execute();
mView.setResult(result);
}
public class View {
private Presenter mPresenter;
public View() {
mPresenter = new Presenter(this, NfcAdapter.getDefault(activity);
}
public void onViewCreated() {
mPresenter.performCalculation();
}
public void setResult(Result result) {
// do something with the result
}
}
检查这些资源以获取有关MVP及其风味的更多信息:
https://martinfowler.com/eaaDev/uiArchs.html
答案 1 :(得分:0)
我需要进行多步计算或REST调用:
在CalculationFragment的onViewCreated()中,我称val sessionId = presenter.firstCall()as String来获取sessionToken以便进一步使用 处理。然后,演示者通过REST检索sessionToken。所以 太酷了。然后,我需要链中的下一个通话,这消耗了 检索了sessionToken和一个NfcAdapter.getDefaultAdapter(活动)。
如果我正确理解了您的问题,
获取API令牌,然后自动进行另一个REST API调用的最常见方法,可能是使用 okhttp Authenticator 和 Interceptor 。