3

I come from a desktop (Winforms/WPF) background were I was the sole developer in the company, and have recently changed jobs to become a part of a team doing web development. I am very much in learning mode as I've only been here a month. We use C#, Entity Framework, ASP MVC, Razor Views.

I've noticed that the code is very repetitive, for example we will have:

public partial class Customer
{
   public int CustomerID { get; get; }
   public string Name { get; get; }
   public string WebsiteURL { get; set; }
   ...
}

public class CustomerViewModel
{
   public string Name { get; get; }
   public string WebsiteURL { get; set; }
   ...
}

public class CustomerModel
{
   public string Name {get; set; }
   public string WebsiteURL { get; set; }
}

In fact often there is a ListModel class as well, and the attributes are all very similar. And there are a few attributes, these above are just examples. In my previous job I tried to reduce duplication in the code using the principle DRY (don't repeat yourself). I designed the solution using inheritance and composition so that if something had to be changed, it usually only had to be changed in one place.

Is this sort of duplication common in web development, and is it considered acceptable practice?

  • Normally I would just use Customer... why is it a partial? – Ewan Jan 28 at 10:15
  • Hi, welcome to softwareengineering.stackexchange.com. Your questions seems to be off-topic for this site as you are asking an arguably subjective question. Please take a moment to read softwareengineering.stackexchange.com/help/dont-ask. – Benni Jan 28 at 15:32
  • The pattern your application is using is called MVVM (Model-View-ViewModel). Please take time to understand what problems the pattern is solving and how it solves them. However, my viewpoint is somewhat controversial it seems.... The ViewModel should have a property called Model so the UI can bind directly too it. So, is Customer supposed to be a view (hence the partial)? It seems odd to me to see the undecorated name be anything other than the model. – Berin Loritsch Jan 28 at 18:31
  • 1
    @Benni: I disagree, I can backup this observation that these kinds of duplication very often happen in multilayered systems, and there is nothing opinionated about it, this is quite factual. – Doc Brown Jan 31 at 6:52
4

You do sometimes get duplication in the view, as its common for the presentation layer to initially be the same as the business models, but then change as presentation features are added.

However, I would not normally expect as much as you indicate. Perhaps the team has got into a pattern that isn't helpful.

I would have:

public class Customer // this is the model an exists in a separate assembly
{
}

public class CustomerListPageViewModel
{
    public List<Customer> Customers {get;set;} //this is the list of customers you are looking at. No need for a seperate CustomerViewModel
    public PaginationOptions {get;set;} //this is the pagination meta data, what page, what sort options etc etc

    public bool extraViewSpecificThing {get;set;} //what buttons are visible etc

    public string GetCustomerFullName(Customer c) {...} //view specific logic to transform the customer. In this case add the first and last name or whatever

}

and then in the Razor view you omit or alter as required the various properties of customer that you are displaying.

Obviously, if you start having lists of customers all over the place you get duplicate GetCustomerFullName functions in all your views and it becomes sensible to create a ListedCustomerViewModel or whatever to encapsulate that. But I wouldn't start with that.

4

Nobody says you must have XModel and XViewModel for every X in the domain model. If CustomerViewModel is just a copy of the data in Customer, then it is superfluous.

ViewModels are introduced because it is often useful to have a level of indirection between the view and the domain model. But as long as this level of indirection does not add any value (which is doesn't in your case where it is just an exact copy) then it is not needed.

A good design principle is YAGNI - don't introduce layers of abstraction until you need them.

1

You are right, in multilayered systems (not just web applications), it is not uncommon to find the same attributes and similar structured data in each of the layers. Data like the customer attributes from your example needs to be passed back and forth between

  • a web front end

  • a view model

  • a view-agnostic model class

  • a database aware access layer

  • a database

(and this is just an example).

This can indeed lead to lots of boilerplate code, not just because of the reptition of those attribute definitions, but also because there will be a lot of quite dumb code needed to pass the data between those layers. However, there are some techniques to mitigate this issue:

  • layers don't need always to be strict, so one could actually introduce data classes which are reused between different layers

  • code generation may allow to create data classes from a db schema or vice versa

  • ORM mappers may also incorporate code generation and reduce the need for boilerplate code a lot

  • object mappers like Automapper are another approach to map similar data between classes of different layers without writing code, by using conventions or additional meta data

  • meta data, for example attribute annotations, may be used to add information to data objects to make the transition to other layers simple. For example, a "DisplayName" annotation can be used to create view labels for data attributes automatically

  • "data binding" of several UI frameworks is often based on such meta data, and will also help to avoid the need for writing too much "boring" code

In the end, it is a trade-off: multi-layer abstraction (as any other kind of abstraction) comes for a cost. For very small applications, you better try to use as few layers as possible. For larger applications, it will probably pay off to use the tools I mentioned above. Pick your poison.

  • There is also the functional aspect, the OP didn't developped that point but maybe he's currently working now in a classic data-management oriented application where he passes a lot of time to make forms and save them to database. The cumulation of both the multi-layered and repetitive forms developping are effectively generally quite boring and lack of challenges. – Walfrat Jan 31 at 10:08

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.