0

I'm fairly new to MVC and I'm trying to get a better understanding of it. There is endless information about the theory and general responsibilities of each part of an MVC app, which I've read a good deal of, but I find myself constantly second guessing my implementation.

I currently have my application setup where my "Model" provides a number of methods that effectively do CRUD work on the application data. Methods like add_document(name, path) and update_account(id, code, name, status) At this point it works, but it feels clunky, as I effectively have to decide whether I want to write a method to update every property of a model object, or whether I want one method that can handle updating any property for a given object. These methods all interact with model objects in SQLAlchemy (A Python db toolkit and ORM). Lately I've considered the possibility of passing ORM objects back and forth between the Model and Controller. The controller would change a property, then pass the object back to the Model which would handle sessions, commits, and error conditions. While this seems so much easier than writing tons of CRUD methods, it also seems to break the division of responsibility by allowing the Controller to touch ORM objects at all...

I was hoping to get some guidance here. Are a whole ton of CRUD operations normal in MVC apps? Is it acceptable to pass ORM objects between the Model and Controller - where the Controller only ever updates properties while the model handles session and database work? I'm also open to alternative ideas about how to separate responsibilities in an elegant way.

2 Answers 2

2

Model methods don't have to be all CRUD. What you probably need is a Service Layer.

The Service Layer provides an abstraction between your database persistence operations and your business operations. On one side of the service layer, you have calls to CRUD methods and whatever other resources you need to fulfill service requests. On the other side of the service layer, you have methods that execute business transactions:

public bool MoveMoney(guid SourceAccount, guidTargetAccount, SecurityToken token);
public OrderStatus PostOrder(int AccountID, int OrderID);

Its these methods that your controller will call, not the CRUD methods.

1

Oh-keeey.

What you are getting wrong about Model ..

You have to understand, that "Model" in MVC is not a concrete object or a class. Instead it is one of two major layer in application:

  • model layer contains the "business logic", it's where most of the 'interesting parts' are located
  • presentation layer deals with the interface through which user can interact with this "business logic"

Note: as you might already notice, it is perfectly alright to have several presentation layers in parallel. Though it's rare "in the wild".

Your presentation layer (which consists of views and controllers) interacts with model layer though services. Said services contain the interaction between domain objects and data mappers. That part goes by the name "application logic".

For example: if you had a service Library, it manipulate and the exchange between User and Book instance and pass them to different data mappers for persistence. The service doesn't really care how the isValid() method works internally for for the User instance. Neither does it cares where the user is saved, when you call mapper.store(user).

The domain objects in the model layer are the code representation of 'Domain Model' (to learn what it is, see this book). Basically, they will contain all the business rules, conditions and ideas on which the application is based upon.

And the third major group of structures within model layer are usually data mappers. The are dealing with persistence logic goes. It's where your CRUD code actually exists. And part of persistence logic is the data integrity checks. If, when inserting new email address in the some table, you get an exception regarding UNIQUE constraint violation, data mappers is where you handle it. Whether you do it by setting an error state on the domain object which you where manipulating or you kick up/return an error code to service, it's your preference (I like the former approach).

Note: mappers can persist data in any medium that like: sql, nosql, files, remote rest api, /dev/null or crystalline fairy dust. And, if you make sure that the all have same public interface, you can use multiple data mappers on the same domain object. That would let you populate the infamous User instance from sql, cache and session. Simply by passing it to three different mappers with mapper->fetch(user) calls

So .. where are Controllers in all this

The controllers, according to MVC pattern, have a very specific responsibility: altering the state of model layer and (in rare cases) current view. That it.

Controllers do not know anything about CRUD. Controllers do not get data from model layer. Controllers do not initialize or render views. None of it.

Note: there are edge cases, where in desktop applications (or in situations when, within application's lifetime, there are multiple users interacting with it ... not applicable to web) the controller can observe model layer for changes. And, based on specific change, unlock additional functionality for same user's interaction. I have never seen it in practice.

This also means that your views must be real objects and not just dumb templates, because, since controller isn't pulling any data from model layer, views have to decide, what information they need and request it themselves.

Such fully-implemented views will usually be juggling multiple templates/layouts and presentation objects. From high orbit the will kinda resemble services, because manipulation of templates and presentation objects will vaguely resemble interaction between data mappers and domain objects.

my 2 cents

7
  • Controller methods are a switchyard; they provide a working surface by which the user can perform software operations through the UI and the routing engine. They are agnostic from the perspective of functionality; a controller method can compel an MVC application to do anything. They don't always just manipulate state via CRUD, although that functionality is obviously very important. May 6, 2014 at 17:48
  • @RobertHarvey controllers have nothing to do with CRUD.
    – mefisto
    May 6, 2014 at 17:51
  • let us continue this discussion in chat May 6, 2014 at 18:02
  • This is what happens when one reads "don't" as "do" in: 'They don't always just manipulate state via CRUD (..)'. Kinda lame on my part. Removed latter pointless flame.
    – mefisto
    May 6, 2014 at 18:30
  • 1
    The "doubleclick" will go to the controller, which then will execute a command on one of the services. That process will alter the model's state. If you are working on a desktop application, then the view should probably observer the model, and, when model's state is altered in the part which that particular view observer, said view request the needed data from model layer (the account details). Based on what the view got, it displays some kinda of detail window. If you have a web application ,then the flow is a bit different.
    – mefisto
    May 6, 2014 at 19:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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