버그 발생 원인은 휴먼 에러가 대부분이다. 이를 막기 위해선 언어 측면에서 강제할 수 있는 부분을 최대한 활용하여 휴먼 에러를 방지하면 된다. UI는 비즈니스 로직에 관여하면 안 되므로 ViewModel 내부의 데이터를 UI 측에서 읽기 가능으로 만들면 관여할 수 없게 된다.
ViewModel에 State가 너무 많을 경우 유지 보수에 문제가 된다. 따라서 모든 상태를 가지고 있는 State 클래스를 별도로 정의해 View 측에서는 State만 보고 UI 작성을 할 수 있도록 한다.
class MainViewModel {
final SocialLogin _socialLogin;
bool isLogined = false;
User? user;
MainViewModel(this._socialLogin);
class MainState {
bool isLogined = false;
User? user;
}
class MainViewModel {
final SocialLogin _socialLogin;
State state = MainState();
MainViewModel(this._socialLogin);
class _MyHomePageState extends State<MyHomePage> {
final viewModel = MainViewModel(KakaoLogin());
final state = viewModel.state;
Widget build(BuildContext context) {
한 화면 내에서 수행할 모든 기능 수 만큼 메서드가 많아지면 코드의 복잡도 증가하므로 state와 마찬가지로 모아준다.
상황에 맞게 Event 또는 Action, UiEvent 등과 같은 이름으로 사용하면 된다. (사용자 액션 = Action, 그 외 Event) 다른 언어(kotlin 등)에서는 sealed class (봉인 클래스) 라는 기능으로 제공한다.
abstract class Action {
factory Action.login() = Login;
factory Action.logout() = Logout;
factory Action.getUserInfo(String name) = GetUserInfo;
}
class Login implements Action {}
class Logout implements Action {}
class GetUserInfo implements Action {
final String name;
GetUserInfo(this.name);
}
void onAction(CalculatorAction action) {
}
각 기능별 메서드는 private로 비공개하고 onAction (또는 onEvent)을 통해서만 기능에 접근하도록 제한하면 view에서 상태는 state만 보면 되고 기능은 onAction()만 호출하면 된다.