Page 1 of 3

A single core class throughout a framework

Posted: Mon Jun 01, 2009 6:54 pm
by lastkarrde
I have a class called $core. It's a singleton and it can be overloaded with objects using the __set() method.

The rest of the framework is made up of modules and extensions. The user can specify them to be automatically loaded or can load them manually in the code. When they are 'loaded', a new instance of the class is attached to the $core object. For example if the mysql module was loaded and I wanted to execute a database query then I would:

$core->mysql->query('foobar');

Likewise if the benchmark extension was loaded you would:

$core->benchmark->start('preQuery');

(Hopefully you get the idea).

The advantages are obvious - you can call the $core singleton anywhere and get the full functionality of the rest of the framework (if the module/extension is loaded). I personally can't see any disadvantages of doing this - but I haven't been coding PHP OOP for very long so any comments or criticism on this approach is much appreciated.

Re: A single core class throughout a framework

Posted: Mon Jun 01, 2009 8:39 pm
by allspiritseve
lastkarrde wrote:The advantages are obvious - you can call the $core singleton anywhere and get the full functionality of the rest of the framework (if the module/extension is loaded). I personally can't see any disadvantages of doing this - but I haven't been coding PHP OOP for very long so any comments or criticism on this approach is much appreciated.
This is called a registry-- and I would recommend passing it around in constructors rather than calling it statically. The disadvantage to doing it your way is that you can't tell what dependencies an object has, since the core class can be called from anywhere. Of course, even passing around a registry is less indicative than passing specific dependencies in the constructor, but it is still better than a singleton registry.

Re: A single core class throughout a framework

Posted: Wed Jun 03, 2009 2:20 am
by Benjamin
I've done that before when I built a framework. I can't say anything negative about it.

Re: A single core class throughout a framework

Posted: Thu Jun 04, 2009 3:43 pm
by Darhazer
allspiritseve wrote: This is called a registry-- and I would recommend passing it around in constructors rather than calling it statically. The disadvantage to doing it your way is that you can't tell what dependencies an object has, since the core class can be called from anywhere. Of course, even passing around a registry is less indicative than passing specific dependencies in the constructor, but it is still better than a singleton registry.
Well, no matter how you make the database abstraction, for example, if you use the DB class wherever you want some data, there is no matter if you use a global Registry or just use the DB class... Unless the developer do not enforce himself to use the Domain classes for the data, hence to use data abstraction, there is no matter if you have registry or not. Passing it to the constructor is useless. In my opinion the only case you have to pass Registry object in a constructor, if you allow the existence of different registries. If you have only one registry, as the described case, better use Singleton registry.

Re: A single core class throughout a framework

Posted: Thu Jun 04, 2009 3:52 pm
by Christopher
Darhazer wrote:In my opinion the only case you have to pass Registry object in a constructor, if you allow the existence of different registries. If you have only one registry, as the described case, better use Singleton registry.
Not just multiple Registries, but a different Registry. Remember that when you use a Singleton you are hard-coding a name into your code.

Re: A single core class throughout a framework

Posted: Thu Jun 04, 2009 4:33 pm
by allspiritseve
Darhazer wrote:Well, no matter how you make the database abstraction, for example, if you use the DB class wherever you want some data, there is no matter if you use a global Registry or just use the DB class... Unless the developer do not enforce himself to use the Domain classes for the data, hence to use data abstraction, there is no matter if you have registry or not. Passing it to the constructor is useless. In my opinion the only case you have to pass Registry object in a constructor, if you allow the existence of different registries. If you have only one registry, as the described case, better use Singleton registry.
I think it does matter whether you're calling a registry statically or passing it in the constructor. With the latter you still have control over who has access to the registry, so in that regard it is less global. If a class only needs one or two objects from the registry, then it is even better to pass only those dependencies into the constructor.

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 11:42 am
by Benjamin
Technically speaking, it can be more than a registry in the sense that not only does it store instances of classes, but it can load them as well. That's how it works in my framework anyhow.

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 12:18 pm
by Christopher
astions wrote:Technically speaking, it can be more than a registry in the sense that not only does it store instances of classes, but it can load them as well. That's how it works in my framework anyhow.
Yes, that moves it toward the Service Locator idea. This makes sense in PHP because including files is done in a unique way in PHP. Other languages that are OO and have a class loader, whereas PHP's include is just a generic code loader.

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 2:39 pm
by Weirdan
lastkarrde wrote:The advantages are obvious - you can call the $core singleton anywhere and get the full functionality of the rest of the framework
That's exactly a disadvantage, as it creates invisible dependencies.

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 4:59 pm
by Benjamin
Weirdan wrote:
lastkarrde wrote:The advantages are obvious - you can call the $core singleton anywhere and get the full functionality of the rest of the framework
That's exactly a disadvantage, as it creates invisible dependencies.
What are invisible dependencies and how are they a disadvantage? I think I get what your saying.

If you have a framework with lots of little pieces that work with and depend on each other, you inherit dependencies because it (the framework code base) functions as a cohesive unit. The pieces are not designed to be used independent of the framework, so I would conclude that these dependencies are not a disadvantage.

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 5:14 pm
by allspiritseve
astions wrote:What are invisible dependencies and how are they a disadvantage? I think I get what your saying. If you have a framework with lots of little pieces that work with and depend on each other, you inherit dependencies because it (the framework code base) functions as a cohesive unit. The pieces are not designed to be used independent of the framework, so I would conclude that these dependencies are not a disadvantage.
Every class you use that needs another class to do its job has a dependency on that class, whether it's using framework classes, using a db connection, or even just delegating to another class to do some calculation. Unless your class is entirely self-contained, it has dependencies. These dependencies can be explicit if they are passed in the constructor or a setter method. You can easily see what is needed for a class to function. If there's a static call inside of a class, it's not easy to see that the dependency is there unless you are reading the actual code. If you don't know about a dependency, it's hard to understand how the class works, harder to test it, and harder to modify it to your needs. I'm sure others with more experience can explain it more elegantly than I can, but that should give you an idea.

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 7:45 pm
by Weirdan
astions wrote:The pieces are not designed to be used independent of the framework, so I would conclude that these dependencies are not a disadvantage.
If they are not designed to be used independently it's probably not a good design, at least it's the design that does not promote code reuse. Here's a recent example from my own experience:
Currently we're working on large educational service for UK market; the team consists of about ten people, so communication issues are starting to rear their heads, but it's not that bad yet. A week ago I started writing some background batch services (generating periodic reports, mailing users, aggregating data, etc). Naturally I'd like to reuse data access methods that were already there. Much to my surprise I couldn't use many of them because they relied on data from session to construct sql queries. This is an example of invisible dependency, the one I wasn't aware of, and the one that's not easy to get rid of. The person who coded them was of similar mindset to you: "We're building a web application, so surely session would be there, right?"

The moral of the story is: when you are writing code you don't know how people will use it. Either because you actually don't know (like my colleague did not know) or because requirements will change later. The less your code assumes about its environment - the easier it's to use, re-use and adapt.

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 8:13 pm
by Christopher
Weirdan, your example is about Dependencies but also about about Responsibilities (and good design). I recently had a good experience for the same reason you had a bad one. I moved a site to a CMS but there was a search that had a distance feature that used Google Maps API. There was a nice Model class to get search results from. Inside that Model there was a dependency on a Google Maps class that used Snoopy to go out and do the web services call. When I moved it over it worked fine even though there were hidden dependencies.

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 8:41 pm
by Weirdan
arborint wrote:When I moved it over it worked fine even though there were hidden dependencies.
Well, you were lucky the CMS used Snoopy too (if I read you correctly). But why take chances when you could have had a class that made its dependencies explicit?

Re: A single core class throughout a framework

Posted: Fri Jun 05, 2009 9:30 pm
by Christopher
Weirdan wrote:Well, you were lucky the CMS used Snoopy too (if I read you correctly). But why take chances when you could have had a class that made its dependencies explicit?
It didn't, but it said include_once 'Snoopy.php;' at the top of the file -- which gave me a good hint. ;) Had the project you were working on properly put the session data behind a clear interface then you could have perhaps coded a replacement to make it work (without needing changing their code). That would also have forced them to abstract where the data was coming from.

My point is that dependencies are often hidden. Those hidden dependencies should be even more carefully designed for modularity and layering than the visible ones.