Lock
Lock

Reputation: 5522

Where to place classes which aren't models but act on models

In an MVC pattern, what is the best way to describe classes which aren't exactly models, but they work on models?

For example, I have an Order model which represents a customer's order in the system. I want to have a class called Orders which amongst other things, will store a collection of Order and perform functions on those. I don't believe this belongs in the Models folder as it isn't really a model.

Another example is that the user can import orders, so I would have an Import class which handles the import.

I don't believe these are helper classes or plugins so am not really sure where these go in terms of the folder structure.

Any help appreciated!

Edit: Just to describe the point of my Orders class- currently, each Order model has a validate() function which checks an external WMS for stock. This call is VERY expensive (an old FoxPro database) and when importing orders (in which you can import multiple orders at once), rather than having 1 call to the WMS for every order, I wanted to move this validate function 1 level higher so that I can have a single call to the WMS system to get the stock levels. That is why I was going to have a class called Orders. I agree that Orders is really just a collection of Order, however I am unsure where to put this method now. As Engineer Dollery pointed out, the relationship of orders is owned by the customer (a customer has many orders), however it doesn't right to me the the function belongs on the customer.

Upvotes: 2

Views: 135

Answers (2)

Software Engineer
Software Engineer

Reputation: 16140

You sound a little confused about what a 'model' is.

A model is usually thought of as the related set of objects that describe your business domain. In your case you have a customer that has orders -- it could be said that your model has a 1-many relationship between customer and order, and that the relationship itself is called 'Orders'. If you view things this way, then the methods you describe probably belong on the owner of the relationship -- in this case, customer.

You may also have a need to represent all the orders for your company, not just for one customer. You could achieve this through navigation (loop through all customers and retrieve all orders for the customer), or you could model it as your Company has a 1-many relationship with Order -- in this case, again, you would put the methods you're describing on the Company object.

If you think about it, only a customer, or your company, can view and change orders. If you have an external 'thing' doing something with the orders you should find out what that thing is and represent it in your model. Every read or write to your data should go through your model.

Edit

You mention that 'the user can import orders', and assuming that 'user' is synonymous with 'customer', then the import method should be on the customer interface.

Now, you talk in your edit about performance issues -- the validate method being very slow -- so you want to optimise it by validating many orders simultaneously. This is actually an implementation detail, not an interface detail (at least, not in your public interface).

You point out that you have an Orders object, which sounds ok to me, but this probably shouldn't be published via your customer interface (your user doesn't need to know about it). The Orders object should be the holder of the orders collection and it should belong to a customer (customer has orders) -- and the customer implementation should delegate the validate command to the Orders object which can optimize this any way it needs to.

This means that a customer doesn't know how to validate an order (which makes sense), but that Orders (your object) does. If it weren't for your performance constraint you could implement validate on orders in the simplest of ways (iterate through orders calling validate), however you do have the constraint so you'll probably have to build some sort of validation object populated with info from the collection of orders, pass it off to your validation service, and react to the response by setting a valid flag on the individual orders.

References

I'd take a look at the book, 'Implementing Domain Driven Design' by Vaughn Vernon, which can be found on amazon.

Upvotes: 2

Jon
Jon

Reputation: 437584

In an MVC context the classes you describe certainly sound like models.

Keep in mind that "models" as a term is not constrained to refer to single business objects. Anything that represents an operation implementing business logic (such as an Import) is also a model.

The situation with the Orders class is less clear because that sounds simply like a collection of orders and it isn't clear why the class itself would need to perform functions on the orders (vs. just allowing clients to enumerate the orders and perform the functions themselves). I would say that it's simply a not very appropriate example for this case.

Upvotes: 1

Related Questions