I’m using the light-weight PHP Fat-Free Framework as a base to form a simple MVC based app with DDD philosophy for the Model layer. I’m aware that DDD is most suitable or enterprise solutions and that applying DDD to simple, mostly data-driven apps is kind of an overkill, but there are some concepts in DDD that I find appealing (like the Repository pattern, business logic in Entities, etc.) which I’d like to apply to my app.
Fat-Free Faramework has a Base class that represents the application (a Singleton) and the instance of Base holds a lot of useful tool methods and a registry of global framework variables (the hive) which is used, among other things, for configuration data.
As I’m writing my app, I find myself using a lot of Base class tools inside classes in the Model layer, and I’m a bit confused by how to reference the Base instance in those classes. Do I simply call Base:instance() inside model classes or do I inject it through the constructor as a dependency? Dependency injection seems like the proper way to do it, but since most of the app will depend on it, the whole reference passing through the constructor seems unnecessary. Also, how to pass for an example database config data to data persistance classes which is stored in the hive? Should it be passed by the Controllers when instantiating Repositories or called directly from the Repository (or Data Mapper)? I’m looking for a way which won’t fire back on me, so I’m looking for any insight or advice on this.
The second part of my problem is that I’m trying to write my app so that each Entity and business logic related to it is configurable from the Entity class. This is an idea inspired by Sails.js I’m still testing out, but for an example, I have a method getProperties() which returns an array of user-defined configuration data for each Entity property, e.g.:
'title' => array( 'type' => 'text', 'minLength' => 30, ... )
or for associations:
'children' => array( 'entity' => 'ChildClass', 'relation' => 'oneToMany' )
It might look a bit controversial, but I’ve tested business logic functionality and so far it works OK for me, and client code communicates with entities via usual get/set/other methods. The idea behind such configuration is to be able to automatically generate scaffolding/administration interface for each Entity, and configure Data Mappers and Repositories based on the related Entity’s getProperties() method.
What’s bugging me now is that if I want to have one place where this configuration data exists, I’d have to place some non-business-domain logic into the Entity, such as an exceptional database table name, whether a field requires a rich-text editor or not, whether a checkbox is checked by default, a certain field used as an Entity’s print identity in the admin web interface, etc.
I realise that the problem I have is a tradeoff between a clean model and the single-place configuration idea and that I’ll probably have to pollute the Entities by storing such non-business-domain data into the Entites, but I thought perhaps someone here might have an idea about how to approach this in a different, or better way?
Thanks for reading.