I am writing an application where most of the legwork is done in the models, the models perform 2 (fairly distinct) groups of tasks:-
CRUD database operations
Create Table, Form and ContentBox objects, populated with with data from the database
Some of the models as a result are quite big, so I have setup the Illuminate Database component from the Laravel framework and I am thinking of using the Eloquent ORM to create models that do the CRUD and then have separate models which generate the Tables and Forms, calling methods in the Eloquent models to get data.
What would be the correct terms for these 2 different 'models' in domain driven design? Do I call the models that do the CRUD entities and the other models models?
I've read a few of the related posts and I understand a model is a model of something in the real world. So for example I've got a model called Invoices which has methods for returning a Form object, for creating a new invoice, and a Table object, for listing all the invoices. But it also has a method for returning a PDF of a single invoice. So this isn't really a model of a single invoice - it has the ability to return data for multiple invoices... is this still a model?
Apologies there are actually 2 questions here, I'm just wondering what the correct terms are, or looking for suggestions to somewhere I can read about this sort of thing, so that I can do something that is considered best practice and will make sense to other programmers.
Thanks in advance.
Update So after reading this it seems to me that what Laravel calls a model (before adding business logic to it) is in fact an entity. So what I'm planning to do is have a folder called Entities with my ORM 'models' in and another folder called Models with the business logic 'models' in - is this common practice?
I don't think Table or Form are domain models in your case.
Domain models are reflection of your core business concepts. For example, you can answer whether an Invoice is overdue by call invoice.isOverdue()
On the other hand, Table for listing invoices, outport pdfs are responsible for taking care of presentation concerns.
Presetation components have dependence on Domain objects, but not vice versa. For example, you may list Invoices on a html page or outport Invoices by pdf. But you probably don't want the code looks like this:
public class Invoice {
Table list() {...}
File outport() {....}
...add another method for excel maybe?
}
You may interested in this post for the component's responsibilities.
It's common practice to setup what are models in laravel in the Models folder. I believe what you are looking for are called repositories which you'd make a folder for, and add it to the autoload section in your composer.json file.
It's considered good practice to have lightweight controllers and models aren't really intended to contain all the extra logic, so having repositories where you'd put all the heavy lifting would help keep your app very organized.
Related
I am currently looking to redesign a feature on my web application.
The web application utilizes Yii (version 1) for the back-end.
In this instance I have a model and controller. The model is used to store all the userTracking data and is appropriately a userTracking model however the actual logic for the model is in a controller called UserController. I have a function called actionTrackUser($id) which is used to implement various tracking logic for a particular user and create a model for that user.
I however now need to extrapolate this functionality from the UserController to a seperate trackingController which will implement tracking for various models.
I need to be able to utilize this functionality however in the new controller and old controller. I was wondering as to the best approach for this in Yii 1 that implements MVC correctly. I thought about making a trackingModel and having the userTracking model extend that but then I would have a lot of business logic in a model in order to use it in two places.
I am fairly new to MVC and Yii so I was wondering as to the best approach to take here?
I have purposely left code out of this question as it is more a theoretical question regarding the implementation of such functionality in Yii.
Any help is appreciated.
Thanks!
I am not sure that there may be a 'best' approach. However, you need to choose an approach that works best for you. Be guided by what will work for your situation, and what will make manageable code for you and others in the future.
There is nothing wrong with your current userTracking model and controller. You state that the "actual logic for the model is in a controller." You may want to relook at that to move appropriate data management, constraints and validation rules to the model at least.
You can move functions to a separate trackingController and still use the userTracking model. There is no rules that says you have to have a matching model and controller set, and it is quite possible for a controller to manage more that one model at a time.
I generally start with activeRecord models, which map against data stores (database tables in most cases). I use corresponding Form models to reflect forms that are markedly different from activeRecord models, and I use domain models to reflect complex business objects that are feature rich, and reflect lots of runtime attributes (like calculated fields) and state data (like publish state, which are calculated from other fields - for example a user could have validation status, paid status, active status, account level and so on that all work together to indicate what activity is possible for the user).
I have a question regarding a custom mvc framework. I am a little confused with how I should implement the models portion. I am thinking since doctrine entities will be my models, then I could create another folder named models in my file structure and within this model folder I will have individual files that will perform the crud functionality. The reason I am trying to do my own framework is that I plan to use dojo mvc on the front-end.
for instance my models folder would look like:
models --> users
logger
blog
and inside say users class some code my look like:
class Users{
public function getUsers(){
$users = $this->em->getRepository('entities\Users')->findAll();
echo // the data from
}
// also there will be setUsers, etc...
}
Thanks everyone
With in the MVC's Model (at least to my comprehension), the Doctrine should be dealing only with information storage and retrieval for Domain Objects.
And, depending on how you actually implement the front-end part, you might have a very thin interface (that's what views and controller provide) over the model layer, which basically just provides REST API.
Materials you might be interested in:
GUI Architectures
SOLID principles
Law of Demeter
.. added the last two, because your code bit feels a bit off.
I am building a CRM using a framework (codeigniter) for the first time and I am having trouble determining where a certain module should go while maintaining the MVC methodology. The module automatically generates a new user (when a new company is created) and emails the log in details out to the supplied email address.
I am familiar with the idea of skinny controllers and fat models but to compile all the information needed the module must request data from several different tables as well as inserting data into several tables.
The scenarios I have considered so far:
The logic is in the model where most of the information comes from.
Create a totally new model that deals with just this module and the multiple tables required.
Place the logic in the controller that deals with creating a company.
Create a new library or helper and call the module when it is needed.
Skinny controllers and fat models seem to suggest that one or two are the right options but I was lead to believe that a model should only deal with one table in the database.
What is the right approach to ensure adherence with MVC?
Codeigniter allows you to be flexible with your MVC approach. So the answer is which option is:
Easiest for you (or your team) to understand
Easiest to code maintain
Easiest for someone else to understand
There's no point putting your code into a library, if you dont have any other libraries and dont understand libraries. Same as if all your models are "fat", but only point to one table, do you want this model to be the only one that also points to 4 other tables?
Personally, if this "logic" only ever happens in one place, then I would place it into the controller, and call the 4x models you need to do each bit of the code.
If this "logic" occurs in multiple places, I would place it into a library and call it when needed.
i am using Zend Framework to build a web interface for setting up ACL - permission rights - for users of a custom CMS. Since the ACL data is spread in 5 tables(users, groups, permissions, urls=action+controller, nice permission name for the user to understand) and i have only one controller with the four basic CRUD(create, list, update, delete) operations i was wondering what is the best way to do it?
All the examples in my books i've seen that each model extend Zend_Db_Table_Abstract and thus represents one table.
I was thinking i have to do a model that doesn't extend zend_db_table_abstract and then write the queries that i need by hand thus limiting myself to mysql database only?
p.s. please do not argue over the acl database structure
thank you
The definition of the Table Data Gateway pattern is
An object that acts as a Gateway to a database table. One instance handles all the rows in the table.
That's why you won't see it used any differently in Zend Framework. It's a Data Source Architectural Patterns while the thing you are asking about is a Domain specific class.
What you are encountering is Impedance Mismatch, meaning your Business Objects dont match the structure of your Database Design. The common solution is to use a DataMapper or an ORM to handle that for you.
The other solution would be to create a View in your database that joins the tables in a way that maps 1:1 to your required business objects. Then add a Zend_Db_Table for that view. You'd still have to come up with custom create, update, delete logic though. That's not data mapping though, but if you don't have any Business/Domain classes to map to, it's fine.
My understanding of the MVC is as follows (incase it's horribly wrong, I am afterall new to it)
Models are the things that interface with the database
Views are the design/layout of the page
Controllers are where everything starts and are essentially the page logic
I'm using CodeIgniter but I would hazard a guess it's not just limited to that or possibly even just to PHP frameworks.
Where do I put global classes?
I may have a model for Products and I then run a query that collects 20 products from the database. Do I now make 20 models or should I have a separate class for it, if the latter, where do I put this class (other controllers will need to use it too)
Model is the wrong word to use when discussing what to do with products: each product is a value object (VO) (or data transfer objet/DTO, whatever fits in your mouth better). Value objects generally have the same fields that a table contains. In your case ProductVO should have the fields that are in Products table.
Model is a Data Access Object (DAO) that has methods like
findByPk --> returns a single value object
findAll --> returns a collection of value objects (0-n)
etc.
In your case you would have a ProductDAO that has something like the above methods. This ProductDAO would then return ProductVO's and collections of them.
Data Access Objects can also return Business Objects (BO) which may contain multiple VO's and additional methods that are business case specific.
Addendum:
In your controller you call a ProductDAO to find the products you want.
The returned ProductVO(s) are then passed to the view (as request attributes in Java). The view then loops through/displays the data from the productVO's.
Model is part of your application where business logic happens. Model represents real life relations and dependencies between objects, like: Employee reports to a Manager, Manager supervises many Employees, Manager can assign Task to Employee, Task sends out notification when overdue. Model CAN and most often DO interface with database, but this is not a requirement.
View is basically everything that can be displayed or help in displaying. View contains templates, template objects, handles template composition and nesting, wraps with headers and footers, and produces output in one of well known formats (X/HTML, but also XML, RSS/Atom, CSV).
Controller is a translation layer that translates user actions to model operations. In other words, it tells model what to do and returns a response. Controller methods should be as small as possible and all business processing should be done in Model, and view logic processing should take place in View.
Now, back to your question. It really depends if you need separate class for each product. In most cases, one class will suffice and 20 instances of it should be created. As products represent business logic it should belong to Model part of your application.
In CakePHP there are 3 more "parts" :
Behaviors
Components
Helpers
Logic that are used by many models should be made as a behavior. I do not know if CodeIgniter have this logic or not, but if it doesnt, I would try to implement it as such. You can read about behaviors here.
(Components helps controller share logic and helpers help views in the same way).
The simplest way is to:
Have a model class per database table. In this case it would be an object that held all the Product details.
Put these classes into a package/namespace, e.g., com.company.model (Java / C#)
Put the DAO classes into a package like com.company.model.dao
Your view will consume data from the session/request/controller In this case I would have a List<Product>.
Oh, you're using PHP. Dunno how that changes things, but I imagine it has a Collections framework like any modern language.
#Alexander mentions CakePHPs Behaviors, Components and Helpers. These are excellent for abstracting out common functionality. I find the Behaviors particularly useful as of course the bulk of the business logic is carried in the models. I am currently working on a project where we have behaviors like:
Lockable
Publishable
Tagable
Rateable
Commentable
etc.
For code that transcends even the MVC framework i.e. code libraries that you use for various things that are not tied in to the particular framework you are using - in our case things like video encoding classes etc. CakePHP has the vendors folder.
Anything that effectively has nothing to do with CakePHP goes in there.
I suspect CodeIgniter doesn't have quite as flexible a structure, it's smaller and lighter than CakePHP, but a quick look at the CakePHP Manual to see how Behaviors, Components, Helpers, and the Vendors folder may be helpful.
It should be an easy matter to just include some common helper classes from your models keep nice and DRY