OOP vs. Procedural *Singleton* (edit)
Posted: Fri Oct 20, 2006 5:12 pm
(Inspired by the neighbour topic.)
Okay, am I the only one not jumping for the OOP high and staying "procedural" where common sense just demands it?
Let's take database access. In theory, a database object is a singleton. In OOP you would do the getInstance() caboodle with a code possibly like this:
Or, if you want to have several possible polymorphic database interfaces, you could try globals:
As you can see, due to the limitations of the PHP syntax you cannot avoid an extra line in each busyness logic function (oh, cruel fate, had I a penny for each time I cursed why there were no user-definable superglobals a.k.a. just 'globals' in the usual languages
)
Using a 'registry pattern' would only increase the amount of lines for a simple query, as would any more complicated solutions.
Well, hello 'procedural', a function is global everywhere and is a perfect replacement for all the hassles with singletons. Observe:
If you just cannot break yourself to use a (gasp) global function, you can mask it as OOP if you use a static class (poor man's 'namespace'):
I find it quite silly to use some syntactic fodder to make it look OOP-ish, so I go for the first variant. Here's a bit more of faux code to demonstrate that you can have as much OOP as you want behind the scenes (where you can afford ONCE to use the sloppy 'global' syntax for example)
My own implementation is a bit more flashy, it hides the query result resources, provides higher-level functions for dealing with select results etc., but everything is done by a global database object hidden behind generic DB*() functions. In that way I can change the object and have PostgreSQL instead of MySQL without changing the DB* functions themselves.
Okay, am I the only one not jumping for the OOP high and staying "procedural" where common sense just demands it?
Let's take database access. In theory, a database object is a singleton. In OOP you would do the getInstance() caboodle with a code possibly like this:
Code: Select all
function BusynessLogic() {
$pDatabase =& CDatabase::GetInstance();
$pDatabase->Query("SELECT * FROM `table`");
...
}Code: Select all
class CBaseDatabase {/*;)*/
function Query($sQuery) {
return false;
}
};
class CMysqlDatabase extends CBaseDatabase {
function Query($sQuery) {
return mysql_query($sQuery);
}
};
//choose a database type ... silly, I know, but let's pretend
if (...)
$g_pDatabase =& new CMysqlDatabase();
else
$g_pDatabase =& new CPostgreDatabase();
function BusynessLogic() {
global $g_pDatabase;
$g_pDatabase->Query("SELECT * FROM `table`");
...
}As you can see, due to the limitations of the PHP syntax you cannot avoid an extra line in each busyness logic function (oh, cruel fate, had I a penny for each time I cursed why there were no user-definable superglobals a.k.a. just 'globals' in the usual languages
Using a 'registry pattern' would only increase the amount of lines for a simple query, as would any more complicated solutions.
Well, hello 'procedural', a function is global everywhere and is a perfect replacement for all the hassles with singletons. Observe:
Code: Select all
function BusynessLogic() {
DBQuery("SELECT * FROM `table`");
}If you just cannot break yourself to use a (gasp) global function, you can mask it as OOP if you use a static class (poor man's 'namespace'):
Code: Select all
function BusynessLogic() {
DB::Query("SELECT * FROM `table`");
}Code: Select all
class CMysqlDatabase extends CBaseDatabase {
function Query($sQuery) {
return mysql_query($sQuery);
}
};
//choose a database type ... silly, I know, but let's pretend
if (...)
$g_pDatabase =& new CMysqlDatabase();
else
$g_pDatabase =& new CPostgreDatabase();
function DBQuery($sQuery) {
global $g_pDatabase;
return $g_pDatabase->Query($sQuery);
}My own implementation is a bit more flashy, it hides the query result resources, provides higher-level functions for dealing with select results etc., but everything is done by a global database object hidden behind generic DB*() functions. In that way I can change the object and have PostgreSQL instead of MySQL without changing the DB* functions themselves.