web-dev-qa-db-ja.com

ビューモデルアーキテクチャ

2つの画面があります。

  • アイテムのリストが表示された画面。リスト内のすべてのアイテムに「詳細の表示」と「更新ボタン」があります。
  • アイテム詳細画面。 [詳細を表示]ボタンをクリックすると、アイテムの詳細画面に移動します。

「更新」ボタンをクリックすると、アイテムの状態に基づいて決定を下し、アイテムの更新画面に移動するか、続行する前にユーザーに確認を求める必要があります。

アイテムの詳細画面には、同じ[更新]ボタンがあり、同じロジックがあります。

enter image description here

私が抱えている問題は、更新ロジックが複製されないようにビューモデルをクリーンな方法で実装する方法です。

まず、画面のビューモデルを作成しました。

class ItemListViewModel
{
    public ObservableCollection<ItemViewModel> Items { get; }
}

class ItemDetailsViewModel
{
    // How does this calls ItemViewModel:UpdateCommand ?
    public ICommand UpdateCommand { get; }
}

class ItemViewModel 
{
    public ICommand ShowDetailsCommand { get; }
    public ICommand UpdateCommand { get; }
}

UpdateCommandを共有するために、次のオプションを確認します。

  1. ItemDetailsViewModelにItemViewModelのインスタンスを作成して保持させます。

    class ItemDetailsViewModel
    {
        ItemViewModel _itemViewModel;
       public ICommand UpdateCommand => _itemViewModel.UpdateCommand;
    }
    
  2. ItemDetailsViewModelがItemViewModelから派生するようにします。

    class ItemDetailsViewModel : ItemViewModel
    {
    }
    
  3. 更新ロジックを実装するサービスを使用し、ItemViewModelとItemDetailsViewModelの両方にそれを呼び出させます

    interface IItemService
    {
       void Update();
    }
    

更新ロジックの一部はナビゲーションです。ビューモデルに挿入されるIINavigationServiceがあります。使用する場合は、IItemServiceに渡す必要があります。

どれが一番いいのか、その理由はわかりません。これが私が持っている懸念のいくつかです:

  • オプション#2:ItemViewModelから派生するのは奇妙に思えます。
  • オプション#3:IItemsServiceサービスの使用は魅力的なようですが、このサービスを、実際にストレージに保存している別のアイテムサービスと区別するにはどうすればよいですか?サービスとその「更新」メソッドを見るだけで、ナビゲーションロジックだけでは考えられません。

私はいくつかのアドバイスと推論をいただければ幸いです。

MVVMで見つけた記事や本は単純すぎて、より複雑なシナリオについては説明していません。

3
Daniel

私は3番目のオプションに固執します。

最初のものは明白ではなく、においがします(私見)、結合は常に悪いです。それ以上に、「内部」クラスからボタンを削除することにした場合はどうなりますか?それは「外側」のものを壊します。カップリングすべき避けるべきです。

2つ目は奇妙です。継承は、一部のコードを共有するのではなく、一部の機能を拡張するために使用する必要があります。 2つの完全に異なる画面があるため、親子関係はありません。また、親クラスから機能を削除して子に保持することにした場合はどうなりますか?ほとんどの場合、実装を子クラスに移動しますが、その時点で継承は意味がありません絶対にまったく意味がありません。継承のアイデアが本当に気に入った場合は、少なくとも3番目のクラスを作成することをお勧めします。これは、2人に継承されます。

あなたが言ったように、3番目のオプションの唯一の問題は命名です。しかし、これは常に問題です。 「ItemUpdateButtonProcessor」のような名前を使用することをお勧めします。これにより、更新アクション自体と混同しないようにします(imho)。私はあなたが使用している言語に精通していないので、このトピックに関するいくつかのベストプラクティスがあるかもしれませんが、あなたはその考えを理解していると思います。

2
Nondv