Are current MVVM view model practices a violation of the Single Responsibility Principle?

后端 未结 4 1010
天涯浪人
天涯浪人 2021-02-01 20:02

With current practices (at least with WPF and Silverlight) we see views bound via command bindings in the view model or we at least see view events handled in view models. This

4条回答
  •  别那么骄傲
    2021-02-01 20:33

    No! MVVM does not violate SRP, (the programmer does, lol!)

    There is no reason that using the MVVM pattern needs to ignore the SRP. MVVM does not mean that there is only one Model Class, one View-Model Class, and one View Class. Certainly, if you only had one View Class, you could only ever show one simple screen.

    Those classes that are in the View tier, should be responsible for one thing; doing, deciding, or containing. A View can consist of several sub-views who's jobs are to do certain pieces of the users interractions. Consider a basic form, it has a display grid, items in the grid can be edited, and there is a "Save" button.

    The main View would be a container for two other views; the datagrid (a user control, or something) and a command control. The datagrid then is responsible for choosing the right childview to render data in; in essense it's a container that databinds. The View to edit items is a child view of the datagrid, which is in-turn a child of the main View. Lastly the command control is a set of buttons (in this case a single one) who's single responsibility is to raise signals that commands have been issued by the user.

    In this way the Edit View (used by the DataGrid) is agnostic about what uses it, and has one responsibility; Same with the command control. Likewise the DataGrid doesn't care about who uses it, only that it can contain the Edit View (child). Nice SRP there.

    ViewModels to match the Views (and children) are also responsible for one thing. The Edit View Model is a container to which the Edit View Binds; it simply contains the data fields that can be displayed/edited. It doesn't care about anything but signalling when one of its properties change. The Command Button View Model is a class that does things. It's commands are bound to the buttons, and it will do work based on what the user clicks on. It will have to have access to other parts of the ViewModel(s) to do it's work.

    The main page View Model is there to contain the other child views. It's sole responsibility is as an initializer, making all the required ViewModel instances, and passing constructor parameters to other ViewModel instances (say, the Command Button View Model so it knows where to get data for it's work)

    It's natural to cram a whole bunch of functionality into a single ViewModel that a large View would bind to. But it doesn't have to be that way, and SRP can be maintained in MVVM.

    The main goal of MVVM is to allow for testable design, the Model layer can be tested independantly, all classes in the Model can easily follow SRP. The ViewModel can be tested without the need of a view; it gets trickier to think SRP in the ViewModel, but it is certainly doable; just remember to break out your classes so they only have one concern. The View is bound to parter ViewModels, with any luck, your testing of the ViewModel makes snapping the View(s) on super easy. Remember you can have each View-let adhere to SRP to be part of a larger conglomerate View (container).

    TL;DR? To answer your question directly, the View is a collection of classes that does not break the SRP. Thus, when the ViewModel is abstracted from the View(s) (View-First), they are also a collection of classes that adhere to good SRP.

提交回复
热议问题