Let's say I have the following classes whose instances store their property somewhere for e.x. in a JSON file or a database:
Class Foo
abstract class Foo
{
protected $ID;
protected $title;
// getters and setters
}
Class Bar (extends Foo)
class Bar extends Foo
{
protected $text;
// getters and setters
}
Class Baz (extends also Foo)
class Baz extends Foo
{
protected $tabs = array();
// getters and setters
}
What's the best way to load them from the data source?
How I do it now (not satisfying)
My abstract class Foo
has a method load($ID, PDO $pdo)
. This method is overwritten by Bar
and Baz
which extends the general loading of the title
property in Foo
class with their own properties which have to be loaded.
So in code this would look something like this:
Class Foo
abstract class Foo
{
protected $ID;
protected $title;
public static function load($ID, PDO $pdo)
{
$result = null;
// SQL query for getting $title property into $result
return $result;
}
// getters and setters
}
In the class Bar I do this:
class Bar extends Foo
{
protected $text;
public function __construct(stdClass $data)
{
$this->ID = $data->ID;
$this->text = $data->text;
}
public static function load($ID, $pdo)
{
$generalInfo = parent::load($ID, $pdo);
$result = null;
// PDO query for getting $text property into $result
$generalInfo->text = $result;
return $generalInfo;
}
// getters and setters
}
So this let me call $dataToCreateInstance = Bar::load(4, $pdoInstance)
and returns the needed information to instanciate the specific Bar
object with ID 4.
The probleme here is (as you can see) my classes are bound to PDO also it's really ugly to implement a load
method for each data source so it's not generic at all.
What I want to achieve
I'm looking now for a pattern which let me load those classes from any source. I thought about a Loader
class which looks like this:
class LoaderManager
{
/**
* @var Loader[]
*/
protected $loaders = array();
public function registerLoader($className, $loaderClass)
{
$this->loaders[$className] = $loaderClass;
}
public function loadClass($class, $ID)
{
return $this->loaders[$class]->load($ID);
}
}
and with an abstract Loader class
abstract class Loader
{
public abstract function load($ID);
}
So now I have decoupled the thing. The problem with this attempt is that I have always to provide an additional Loader
for the class itselfs. So for the class Bar
I have to provide at least one of BarLoaderPDO
or BarLoaderJSON
. Which is somehow not that elegant and feels a bit "wrong".
Also there is the problem that I have to store somewhere the mapping which class in the current application has to use which loader.
But it is the only attempt I can think of which leads me to that what I want to achieve.
I like now to discuss and hear if there are other (better) attempts and how to realize them.
Aucun commentaire:
Enregistrer un commentaire