DRY vs Security and Maintainability with MVC and V

2019-03-20 17:35发布

问题:

I like to strive for DRY, and obviously it's not always possible. However, I have to scratch my head over a concept that seems pretty common in MVC, that of the "View Model".

The View Model is designed to only pass the minimum amount of information to the view, for both security, maintainability, and testing concerns. I get that. It makes sense.

However, from a DRY perspective, a View Model is simply duplicating data you already have. The View Model may be temporary, and used only as a DTO, but you're basically maintaing two different versions of the same model which seems to violate the DRY principal.

Do View Models violate DRY? Are they a necessary evil? Do they do more good than bad?

回答1:

This has been brought up time and time again. Not only is it a pretty substantial dupe but the answer is subjective and argumentative. ViewModels are a response to DDD and the concept of persistence ignorance.

To say not using ViewModels is bad means ignoring that Django and Rails and most PHP ORM/MVC frameworks don't care at all about those concepts. Do you want somebody to tell you all those other languages and frameworks are "doing it wrong?".

Whether or not you want to use ViewModels is 100% dependent on what architecture styles you are going for and what the goals of the application are.

This is like asking is dragging and dropping GridViews in a WebForm app appropriate? Depends on a lot of things.

There is also a misconception about DRY that you have here. Do Proxy classes from a WCF service violate DRY? Does the ViewModel contain logic? The primary goal of DRY is to not have duplicated logic with a meaningful purpose. Do a couple of DTOs that share object shapres violate that?

The DDD principal of bounded contexts would make for a good read too. If a ShoppingCart object needs to function differently in a warehouse vs ecommerce website setting does that mean you to share the types? What happens when the only shared functionality is totaling a price ( price + tax + shipping )? Do you create a base class just for that therefore increasing coupling? What are the tradeoffs in time/cost/maintenance for being 100% DRY for a simple method like GetTotal(). Does violating DRY when it makes sense actually decreasing the complexity and overall cost of maintaining your codebase?

I'm sorry for answering with so many questions but hopefully now you can see the nuances and intricacies of the question you asked. ;)



回答2:

One could also note that not using view models would be a violation of the single responsibility principle -- your entity should not be polluted with UI concerns.

I also think the real value of view models doesn't necessarily become apparent in version 1.0 of your application. You will thank yourself when working on version 2.0 when you completely re-think how your back-end works but you don't have to carry those changes out to the view layer.