views:

148

answers:

4

I am writing my own MVC for the purpose of learning it. I have pretty much everything "down-pat" and my main stuff written besides models due to some trouble understanding them and lack of viable examples.

Now, I've been told a model should reprecent a single row, someone told me, your model class should on update/insert and delete rows, anything that involves fetching a single or multiple rows - a "finder" class should be used.

So... a) what is a finder class, b) how do I implement it in a useage example, c) Is what I've been told about models correct or is there a better way than "finders"?

Advice is much appricated :)

A: 

You could implement finders as static methods of the model class:

$foo = ModelFoo::find($id)

konforce
+1  A: 

CakePHP says:

Models represent data and are used in CakePHP applications for data access. A model usually represents a database table but can be used to access anything that stores data such as files, LDAP records, iCal events, or rows in a CSV file.

(http://book.cakephp.org/view/66/Models)

Basically, the model represents persistent storage of your business data. Normally, this is a database.

Once we begin talking about databases and objects, it usually falls into the realm of the much debated 'object-relational mapping' which is how many PHP frameworks implement Models.

A Model usually represents a row in a table, but it could also be a group of rows from multiple tables. A Model could be represented in an infinite number of ways: from something as complex and bloated as a Doctrine db object to something as simple as a text file.

My preferred way of representing models is one-row per model on the main table joined with any related parent tables and containing member objects of any child tables. The only way to effectively implement this is to use a 'Collection' class of some sort so that all the objects can be fetched at once and so you don't make unnecessary queries.

Edit: To directly answer your question, yes, a "finder" or "Collection" class is absolutely necessary if you want to minimize the number of trips to a database. If each model was self sufficient, you'd be doing hundreds of individual 'SELECT FROM table WHERE id=x' queries. A finder or Collection can just SELECT multiple rows and dump the data into Model objects.

Lotus Notes
Unfortunately, CakePHP is wrong. They didn't get the concept. The M in MVC separates application logic from the presentation layer, which is the V and the C (together they form the UI). A model is not just about the data, a model is about the entire domain/business logic. Consider the diagram given at http://martinfowler.com/eaaCatalog/serviceLayer.html for an idea of which layers are part of the model.
Gordon
+1  A: 

Hi Tyler,

The answer is the plain old "it depends".

A model does not have to represent a single row or a collection of rows (I presume you are talking about database data here). Your model should be used to map your business logic entities. Only a subset of your model data require persistence, which could be achieve by interacting with a database.

If we refer to the Doctrine case, this is why the upcoming Doctrine 2 does not force your models to extend from a doctrine record base class.

And I believe this why MVC frameworks like Zend Framework does not provide you with a "Zend_Model" concept. Your models should be implemented case to case.

Jim Li
+2  A: 

It is a common misconception that the M in MVC is just about the database. MVC's main aim is to separate the presentation layer from the remaining application in a way that M does not know about VC.

V and C form the UI, an outer layer by which users can interact with your application. C handles all input requests from V and delegates to M where needed. V displays changes in M. In webbased MVC, V is further separated in content, presentation and behavior, e.g. HTML, CSS and JavaScript.

The application itself is inside the M. It should be able to run isolated from the UI. As such, it does not comprise only the Data Access layer, but virtually all other layers, but the presentation layer. It can, but may not, contain DALs, Service Layers, Domain objects, etc. - whatever is necessary for your application, be it getting data from an RSS feed or pushing data to a Webservice or sendig eMails or calculating Revenue, etc.

Whether a DAL should represent a single row, a table or something else is up to you. It's an essential design choice for your architecture. The four common patterns are Table Data Gateway, Row Data Gateway, Active Record and Data Mapper.

Check out http://martinfowler.com/eaaCatalog/index.html for an overview.

Gordon