As I posted, I received some criticism about my extended MVP pattern over on ScottGu's blog. I wanted to submit my response here, and I'll link to this post in a comment on ScottGu's blog.

I will venture to guess that the vast majority of the folks that read ScottGu's blog are pretty sharp folks. And experienced software developers know that there is no sure-fire solution to every problem; there is no single architecture or design pattern that fits every project; there is no silver bullet so to speak. Microsoft's offering of an MVC framework as well as a Web Form (postback-driven) framework is case in point.

Software architects must analyze the factors of the project at hand, and create a solution that best fits that project. The decision factors are countless, but they include: business requirements, skill sets of the development team, size of the development team, definition of who will maintain the software in the future, and infrastructure & hosting configuration. Because each possible design will have both benefits and disadvantages, it's the job of the architect to choose a design that best fits the project and exposes the least amount of risk.

Some of the projects that I've designed to have omnipotent business objects have actually turned out to be the ones that are the most costly to maintain, and most difficult to train new developers on. With this design, you end up with a lot of implicit, hidden logic. That's the kind of code that can drive you bonkers years later, and will make a newcomer pull out his hair while trying to figure out all of the behind-the-scenes logic of the application. This is why I typically prefer more explicit implementations, and Manager classes help with that.

With manager classes, the logic is separated from the structure of objects and from persistence details. OrderManager.SaveOrder(Order) will work through the process of saving an order, step by step, and there's no other clutter in the class to confuse you. Partial classes help address this too, but Intellisense can still be a bit unwieldy with large entities that have hundreds of properties and methods.

As far as having logic within the controller of an MVC pattern, I can certainly see why that would be debatable. The logic should belong to the business layer many would say. But, I argue that some logic is actually implementation-specific and not absolute. Data entry validation and authorization stand out to me as being implementation specific versus global rules. An example I've dealt with was having to create a branded version of an application. There were many fields that we did not require, but our partner did. So on the branded implementation of the UI, we needed to require a field, but on the standard UI, we did not. As for authorization, you could easily imagine the instance were you have the customer's application filter the user's functions to his or her authorization, but you have an internal application that does not restrict access. Both systems would be working with the same entities, but through different implementations, following different rules.

What it boils down to though is where you want to put the logic. The logic exists no matter what. If you choose to make your entity classes fully self-contained, and then build an ignorant controller and view, that's your prerogative. You might find this easy to build and maintain, but you might find that your business model layer is so complex and bloated with every type of logic, that it becomes difficult to maintain. Meanwhile, spreading the logic out a little so that you have separation of concerns will help each individual layer seem less overwhelming, while still applying all of the same logic. But you do end up with more plumbing to make it all work.

As I discussed earlier, when designing an architecture, you must account for many factors. The project where I designed my MVP pattern was definitely no exception. We wanted to use LLBLGen for creating our entities, but none of us had ever used it before. So, we needed to build against LLBLGen in a way that if we needed to rip it out and replace it with something else, we could. Having the manager classes addressed this--if we replaced the entities, we'd update the manager classes and our presenters to use the new structures, preserving all logic and processing. While we never had to replace LLBLGen, if we had needed to, we could have, and it wouldn't have been painful.

At the end of that project, each of the developers on it was very happy with how it all worked out. In fact, 2 of the other developers moved on to other projects where the same architecture was reapplied successfully. On one of those, LLBLGen was not used because the client had already built their own O/RM. It plugged into the architecture nicely. On the other project, Oracle 7 was used instead of SQL 2005, and LLBLGen took care of that nicely for us. That's a pretty adaptable architecture if you ask me.

I know that the MVP pattern I designed doesn't suit the needs of every project, as no architecture ever will. But it accomplished our goals for us very nicely and resulted in the friendliest user interface of all of my projects.

Thanks Frans! LLBLGen allowed us to do some amazing things with validation with very little trouble. At the end, we were thrilled with your product and determined that using it saved us about 6 man-months on the project.

I'll be posting some more details on my MVP pattern soon, including how we were able to leverage LLBLGen to automate a lot of the validation. Once I get to that aspect, some of the nay-sayers might see that even though we technically had the validation in the presenter layer, it was still driven from the entities as they would want.

Nice article Jeff. I have been using the same approach as you describe in your article for the last year. This approach allows for the objects to be serialized and transported over the wire via web services/wcf without worry.