web-dev-qa-db-ja.com

例外をUIレイヤーにスローするか、自分のVMレイヤーで処理する必要がありますか

次の方法を検討してください。

    public async Task LoginAsync()
    {
        if (!CanLoginAsyncExecute()) throw new ValidationException();

        try
        {
            StartLoading();
            await _authenticationService.LoginAsync(Email, Password);
        }
        catch (LoginException e)
        {
            _logger.Error(e);
            throw;
        }
        catch (ServiceException e)
        {
            _logger.Error(e);
            throw;
        }
    }

このメソッドを呼び出すUIレイヤーに例外をスローするか、ここでエラーを処理するかを決定するのに苦労していますか?これは個人のxamarinプロジェクトなので、VM(ダイアログまたは何かを使用)でエラーを処理できます。ビジネスロジックレイヤーでエラーを「サイレント」に処理し、例外を再スローすることは良い方法ですか? ?メソッドが何もスローしない場合、ログインは成功ですか?または、ログインが成功したことを示すためにブール値または何かを返す必要がありますか?

5
tjugg

ログインエラーは予期しないものではありません。権限のないユーザーがシステムにアクセスしようとする可能性があります。通常のユーザーがタイプミスをしたり、間違ったパスワードを選択したりすることも(かなり一般的ですが)可能です。

したがって、UIは予想される状況に適切に反応するように設計する必要があります。たとえば、2回目と3回目の試行を行います。したがって、論理設計では、ログインの失敗を、呼び出されたビジネスロジックの考えられる出力の1つと見なします。

予期しない状況を処理するには、例外を使用する必要があります。たとえば、サーバーへの接続が失われた場合、またはメモリが不足している場合。この場合、vmで例外をキャッチし、エラーからの回復を試みる(または損傷を制限する)のはごく普通のことです。このサイレントリカバリが失敗した場合にのみ、例外をさらにスローして、Uiに独自のリカバリ手順を実行させる必要があります。

4
Christophe

Viewmodelクラスを構築するとき、私が推奨する基本ルールの1つは次のとおりです。

UIによって呼び出されるメソッドViewModelsが例外をスローすることはありません。代わりに、ビューモデルはいくつかのパブリック状態を変更することでエラーを表現する必要があります。

ログインの例としては、HasLoginErrorreflecting間違った資格情報のようなものを用意し、おそらくいくつかの(Popup)NotificationServiceの王を呼び出してサービス状態についてユーザーに通知することをお勧めします。

Never™は、これがすべての起こり得る例外を知っている状況にのみ当てはまること、そしてもちろんそれらを適切に回復できる場合にのみ当てはまることを意味します。

しかし、私のビューモデルの相互作用のほとんどすべては、巨大なtry-catchブログを使用した場合とまったく同じです。

1
Kai Brummund