9

I've accustomed to all typical domain driven design practices that are prevalent in most of publications and blogs concerned with modern .net programming. It surprised me, hence, that when I spoke with some Django folks they didn't care about persistance ignorance, viewmodels etc.

Lack of persistance ignorance part may seem understandable when you use Active Record in Django or Rails, neverthelsess using domain entities in views looks like pure evil after having worked a bit in ASP.NET MVC land (same with Java mvc frameworks, I guess).

It's not a single case, it pertains to an overwhelming majority of Django/Rails projects (which always were perceived as Überagile).

Why is that? Is it just because of dynamic language features which make practices like DI unnecessary? Or maybe there's to much overengineering in a enterprisy .NET/Java world?

Do you know of any more architectural differences? Are there any lessons to be learned for .net/java world or, on the contrary, is it just that rubist and pythonistas haven't usually worked with big enough projects to understand the advantages of those patterns?

Peter O.
  • 32,158
  • 14
  • 82
  • 96
aaimnr
  • 1,646
  • 1
  • 17
  • 31

2 Answers2

12

Nice, a lot of discussion already. Here's my opinion on the matter:

Usually it's far easier to access the domain model straight for your forms. It's one of those things that give coding in Rails (I don't know Django, but I'm guessing it's the same) a huge productivity boost. There is hardly any coding need: have a database table, build some html and a simple controller in the middle and you're done. Because there is hardly any code involved, you can change faster, that's why it works well in Agile environments.

But, there is a time when this falls short. Sometimes, your application is too complex to make this work properly. That's when you can add ViewModels, Presenters, Facades, or whatever you want to call them. There is nothing stopping you from doing this in Rails or Django. In fact, Rails 3 introduced ActiveModel as a set of mixins to make every object work as easy with forms as when dealing with ActiveRecord.

So the question isn't why are Rails and Django not doing it, but when should I use it? Calling DDD overengineering isn't true either. It's about doing "just enough" to solve the problem that you have. Keep the amount of code and complexity as low as possible, and you will be easier to maintain.

I would agree that there are certainly lessons to be learned from Java/.NET. Usually they have gotten the design pattern thing worked out nicely. But saying that Rubyists and Pythonistas didn't do enough big projects is not true. The power comes in recognizing when you can get away with a simple solution.

I do think Java programmers (I have no experience with .NET programmers) tend to overengineer things. Maybe it's the frameworks they use. It seems to try to force the programmer to do it "The Right Way", thus making it overly complex.

iain
  • 16,204
  • 4
  • 37
  • 41
1

Perhaps this is your opportunity to explain the advantages of a viewmodel, as I personally see it as a complete waste of time and space. While most of my MVC work has been in Rails, I'm currently working in Spring and have so far always interacted directly with the models stored in my relational database.

If you intend to make certain attributes of a model inaccessible, then don't expose them. You can give them further protection in your before_save method or elsewhere if you wish, but is that even necessary, given the likelihood that a user knows the names of the attributes that you've chosen not to expose?

If there are some other reasons why a viewmodel is beneficial, then I'm all ears (or eyes, as the case may be).

Samo
  • 8,202
  • 13
  • 58
  • 95
  • 1
    ViewModels are about UI, models are about the domain. They are not necessarily the same (even if you may *transform* one into the other). – rsenna Dec 13 '10 at 18:40
  • @rsenna: But what's the point in having a ViewModel? Is it somehow easier for a view to interact with a ViewModel than with a model? If so, this seems like a design flaw in the view technology. Or maybe there's some security benefit? But I surely do not see one. – Samo Dec 13 '10 at 18:45
  • @Samo: I don't think there is any flaw; they just are semantically different. Think of points over a map, for instance - to the view, they probably should be represented using pixel coordinates, but must be stored as latitude/longitude pairs in the model... Of course, that does **not** mean that you must keep formal ViewModels definitions in dynamic languages like Python or Ruby (maybe its easier to just use dictionaries, for example) - but it does imply that you should **NOT** simply expose the domain model to the view. – rsenna Dec 13 '10 at 19:23
  • @rsenna: The view could be responsible for translating latitude/longitude into pixels, and the controller or the model itself could be responsible for translating back to latitude/longitude. This translation has to occur somewhere, and I don't see the need for the overhead of a different object to do this translation. We can still expose the same model to the users without exposing attributes that are not useful to them, i.e. latitude and longitude. – Samo Dec 13 '10 at 19:39
  • @Samo - another canonical example would be registration form with password and password confirmation input. Would you add password2 field to your User model just for the sake of this form? – aaimnr Dec 13 '10 at 19:48
  • @deadbeef: Nope, the password2 field is just a text field, not associated with the model. The value then would just be a parameter passed in to my controller when the form is submitted. They can be compared from there, and errors can be shown if they are different. No modification to the model is necessary. Another option would be to compare them with javascript so it doesn't even get submitted to the controller if they don't match. – Samo Dec 13 '10 at 19:50
  • @deadbeef: Also, in Rails a model can have attr_accessor fields that don't get stored in the database. So if I wanted to consider password2 as a property of my model, it does not have to be a persistent property. – Samo Dec 13 '10 at 19:53
  • @Samo: You **could** make an "active" view that translates coordinates. Maybe I don't want to use javascript or flash for that, but it does not matter: you can do anything you want! I'm just showing that the domain model is NOT NECESSARILY the same as the view model - and for someone well versed in logic (as I think all programmers must be) one exception is enough to disprove any statement. I could go on, but something says me that, for any simple example that I'm able to think of, you're gonna think of another slightly more complicated way of doing the same thing. So, no point going further. – rsenna Dec 13 '10 at 20:08
  • @rsenna: I'm not convinced that it's more complicated. The same translation has to take place somewhere... I'm just arguing that it doesn't have to be in a different object. I'm simply asking that someone demonstrate the need to hide the actual model from the view, and so far nobody has done this. I agree with you that in some cases they are semantically different, but that's the reason why model code and view code are separated to begin with: There can be many representations of the model, and none of these representations are the model itself. We're not exposing it, just allowing interaction – Samo Dec 13 '10 at 20:14
  • OK, I'll try to be "diplomatic" here. I see that @Samo is really worried about performance, and that may be the answer to @deadbeef question. We all agree that Ruby is a **slower** environment, when compared to .NET/Java. For instance, there is not really any real "overhead" in create a viewmodel when working with statically compiled languages. OTOH, I also don't think viewmodels are that useful to a dynamic programmer - most of the benefits we static programmers get (intellisense, strong-typed fields etc.) are just not available to them (and they also do not seem to miss them)... – rsenna Dec 13 '10 at 20:26
  • @rsenna: what you say is correct, but I still don't see the benefit to a ViewModel in a statically typed environment either. I don't see how it makes things easier, more secure, etc. To me it's just an extra layer that needs to be managed, and that's a pain in my rear. If I can interact with a model just as easily as I can interact with a ViewModel, then why not just use a model? I can add special translations for the *rare* cases when the model is significantly semantically different from its representations, but that's surely not the normal case. Why do ASP.NET-MVC programmers need them? – Samo Dec 13 '10 at 20:30
  • @Samo: It's not the case only for CRUD views. Anything but that will be about views that do not "fit" to domain models... Beyond that, I can only add that people that regard decoupling and persistence ignorance as Good Things will not expose the model directly to the view, and that statically programmers will probably use a view model/view DTO in order to achieve that. But I cannot convince you that this practice is a Good Thing... I can say that it makes our work easier, it makes unit testing not only easier but also more meaningful, and so forth. But I cannot make you a believer. :-) – rsenna Dec 13 '10 at 20:49
  • @rsenna: If there is an example out there of how this approach makes your work and your testing easier and more meaningful, I'd love to see it. Those sound like good things, but I can't imagine how this practice achieves decoupling... and I'm not familiar with persistence ignorance but from the sounds of it I think that attr_accessor in Rails has that covered without the need for more objects. And I'd definitely like to know how testing gets easier when you introduce new layers to your application. – Samo Dec 13 '10 at 20:55
  • @Samo - So you've never heard of persistence ignorance, a important tenant of DDD and a reason to use viewmodels but you can somehow criticize their usage? Thats like me telling a brain surgeon what drill bit to use. – John Farrell Dec 13 '10 at 22:00
  • @Samo - The comment about testing with new layers is eye opening as well. Do you have classes which generate html, talk to the UI layer, send emails and log something? How do you test discrete pieces of functionality without decoupling, creating more layers and seperating concerns? – John Farrell Dec 13 '10 at 22:03
  • @jfar: Can you explain your comment better? My Models, Views, and Controller are discrete pieces of code and are tested as such. Why do I need to introduce an intermediate layer to decouple my model from my view? A view is just a representation of your model. My unit tests will test my models. My functional tests will test my controllers. And there are different technologies which can test views. So I'm not sure what your issue is. – Samo Dec 13 '10 at 22:11
  • @jfar: Furthermore, I never explicitly criticized Persistence Ignorance, I criticized the need to have a ViewModel layer. If you think that the goal of Persistence Ignorance creates a need for a ViewModel layer, then can you explain why? From what I can tell, this can be achieved (as I mentioned before) with the Rails attr_accessor. In other words, having proprties on the object that only have values while the user interacts with it, and that do not get stored to the database. Why do I need another layer to accomplish this? – Samo Dec 13 '10 at 22:15
  • @jfar: I admit to having next to no exposure to the concept of Persistence Ignorance, which is why I've been asking the entire time (in case you haven't been reading thoroughly) for an example as to why a ViewModel is necessary, and so far no concrete example has been provided. So please, feel free to prove me wrong. Or perhaps make a case as to why it's necessary to have a domain object that doesn't communicate with the database, since transactions are bound to occur anyway. – Samo Dec 13 '10 at 22:25
  • @Samo - I don't think I can help you understand. If you understood what DDD and persistence ignorance tries to accomplish then the usage of ViewModels becomes obvious. – John Farrell Dec 13 '10 at 22:29
  • @jfar: "I don't think I can help you understand" usually implies a lack of understanding on the part of the person who says it. After all, you don't truly know something if you can't teach it to someone else. Perhaps you believe that this is a good thing without having reasons. If, on the other hand, you do have good reasons for believing it's a good thing, then surely you can either list some of them or point me to the useful discussions/material that convinced you of this. – Samo Dec 13 '10 at 22:34
  • @jfar: For example, this discussion (http://stackoverflow.com/questions/905498/what-are-the-benefits-of-persistence-ignorance) shows some nice benefits of PI, but it's not quite enough to sell me, because you're still pushing dependencies onto another layer and creating additional mappings to maintain. Perhaps you can show me something better. – Samo Dec 13 '10 at 22:40
  • @Samo - Fair point. I don't think I can help you understand via the medium of SO comment boxes and provide any additional information you couldn't get by googling it yourself. Here is a good reading list: http://domaindrivendesign.org/books – John Farrell Dec 13 '10 at 22:40