The problems faced by a common model interface in frameworks

Tags:

You sometimes see people asking why the Zend Framework (or some others) don’t provide a library for the Model part in MVC.

While ZF provides data access classes in the form of Zend_Db and related components, it doesn’t provide any concrete examples of how you would implement a model class. This often confuses especially beginners.

Providing a common base model, or an interface for implementing models, does have certain benefits, but it also has some problems…

Definition

Let’s first define what I’m talking about. By “common model interface”, I’m refering to a predefined set of methods any model class needs to implement, or some defined behavior it needs to have. This could include things such as models must provide getFoo and setFoo methods for accessing their properties, they must provide findByFoo for finding instances etc. – or that it can implement the getters and setters using __set and __get magic methods.

Benefits of a common model interface

Framework components would benefit from this, as components such as the proposed Zend_Form_Model would be able to simply conform to the model interface, rather than having to require adapters that wrap the models into an interface the main class understands.

Another benefit would be to programmers using the framework, as there would be less complexity towards them in implementing models. They would have a defined best practice type of approach to work with, or they could use a bundled model library, or some library which supports the interface. When implementing models, they would have a defined behavior their models would need to conform to, which would make it a little less flexible, but it would benefit them by easily providing them with persistence or other features like the modelforms.

Basically, it would make a convention, similar to how controllers and actions are set up, that could streamline development if it was implemented well enough.

Problems of a model interface

The problems are mostly related to implementation. For one, it would make it essentially impossible to utilize any of the model-related functionality if your models don’t conform to the interface, which could be a problem for example when working with code written with another framework in mind.

At that point, you would either have to modify the interface of all the models, or create a wrapper object which can wrap any old-style model, and an adapter or other, that can take a model and wrap it with the wrapper model.

Another implementation issue would be how to make the interface flexible enough, yet easy to implement. For example, basic getters and setters would be relatively simple, but the models would need much more to be able to be used by a generic data persistence layer or other more complex component. If you take a look at the CU_Form_Model_Adapter_Interface, you can see there’s a lot of things the adapter needs to do, in order for the modelform to function.

Conclusion

I think we can safely say that this is a very problematic thing. While it may seem like a simple concept, in practice implementing it so, that it won’t restrict developers too much, or require them to write a lot of extra code, is very tricky.

I don’t think there is an easy way to solve this. An adapter based approach is probably quite sufficient – the adapter allows you to use any model types you like, as long as you write an adapter that can perform the required functionality – actually it doesn’t even have to be able to do everything, for example your adapter could lack the functionality for relations, and instead always return empty arrays for them.

More on models:
Using models as criteria objects for querying the database
Decoupling models from the database: Data Access Object pattern in PHP