ViewModel 方法名称约定

ViewModel method name convention

ViewModel 类 中命名方法的最佳方式是什么?基于其 action/behavior 或 Activity/Fragment?

的生命周期

例如:

以动作命名的方法

override fun onResume() {
    super.onResume()
    viewModel.connect()
}

override fun onPause() {
    super.onPause()
    viewModel.disconnect()
}

override fun onItemCheckedChanged(task: Task, value: Boolean) =
    viewModel.updateTaskStatus(task, value)

方法由Android生命周期

命名
override fun onResume() {
    super.onResume()
    viewModel.onResume()
}

override fun onPause() {
    super.onPause()
    viewModel.onPause()
}

override fun onItemCheckedChanged(task: Task, value: Boolean) =
    viewModel.onItemCheckedChanged(task, value)

网上有几个例子,两种方法都用到了。

在我看来,这些方法应该与生命周期相关,这样View就不需要知道ViewModel背后的逻辑,只需要知道需要调用一个生命周期方法即可。

最好的方法是什么?

没有正确的方法,只要代码干净且容易read/understand。但是,如果您查看 examples Android give,它们显示的方法与您发布的方法相似。

1) 其中一种方法是让一个对象具有由 Android 生命周期(您提到的)命名的方法。

class MyLocationListener {
    public MyLocationListener(Context context, Callback callback) {
        // ...
    }

    void start() {
        // connect to system location service
    }

    void stop() {
        // disconnect from system location service
    }
}

每个函数都在生命周期所有者中手动调用,如下所示:

@Override
public void onStart() {
    super.onStart();
    myLocationListener.start();
    // manage other components that need to respond
    // to the activity lifecycle
}

@Override
public void onStop() {
    super.onStop();
    myLocationListener.stop();
    // manage other components that need to respond
    // to the activity lifecycle
}

2) 然而,如果你想用它们的动作来命名方法,你可以用 OnLifecycleEvent annotation, which was excitingly brought to us in Android Jetpack!例如:

public class MyLocationListener implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void connectListener() {
        ...
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void disconnectListener() {
        ...
    }
}

现在这些方法在 LifecycleObserver which can observe a LifecycleOwner:

的帮助下自动调用
myLifecycleOwner.getLifecycle().addObserver(new MyLocationListener());

LifecycleOwner 通常是 Activity or Fragment。取决于您选择哪一个,但我更喜欢 LifecycleObserver,因为它需要的代码更少,我认为这使它看起来更干净。

如果您对好的 Android 实践和一些可以帮助您的技巧感兴趣,我会推荐一些好的页面:

- Android best practices

- Android tips & tricks

- Android must have libraries

IMO 最好的方法是使用生命周期的名称,原因如下:

  1. 它使视图(片段)变笨了。实际上,只要您将函数命名为 connect(),视图就会做出连接的决定(逻辑)。
  2. 如果现在您想在 onResume() 中执行其他操作(例如刷新数据),会发生什么情况?您是否添加另一个名为 refreshData() 的函数并在 connect() 之后调用它?或者你在connect()之前调用它,因为你知道必须刷新数据才能连接。哎呀,您已经向视图添加了更多隐式逻辑,仅对视图模型的测试将无法捕获。最好只调用 fun onResume() { refreshData(); connect(); }
  3. 一般来说,您应该按照“发生在我身上的事情”来命名所有视图事件。例如。 didPressDowload() orderConfirmed() 等。如果您将其命名为 orderPizza(),这就像一个命令,如果您想使命令失败,例如 fun orderPizza() { if (orderEmpty) return ....},那么该函数将不再执行此操作它在名字中说。 有时它是小语义,但有时它确实可以避免错误,并且让您对如何仅在视图模型中保留逻辑感到困惑。 请参阅 https://redux.js.org/style-guide/style-guide#model-actions-as-events-not-setters 以获取来自网络世界的类似建​​议。