J'essaie actuellement de trouver la meilleure façon de créer mes objets sur mon projet PHP 5.2 actuel. J'ai fondamentalement un registre qui renvoie des objets par des clés. Si le Registre n'a pas d'objet avec la clé spécifiée, il essayera d'en créer un en appelant une méthode usine fournie au registre par construction. Regardez le code suivant à calrify:Modèle de création: "Bastard Factory", une retombée de l'usine abstraite
interface IFactory
{
public function createProduct($key);
}
class Registry
{
private $m_elements = array();
private $m_factory;
public function __construct(IFactory $factory)
{
$this->m_factory = $factory;
}
public function getElement($key)
{
if (!array_key_exists($key, $this->m_elements))
{
$this->m_elements[$key] = $this->m_factory->createProduct($key);
}
return $this->m_elements[$key];
}
}
Parce que j'ai différentes catégories d'objets que je voudrais stocker dans différents registres J'enveloppe un ojet de registre dans un singleton pour chaque catégorie, comme ceci:
class SpecialRegistry
{
private static $instance = null;
public static function getInstance()
{
if(self::$instance === null)
{
self::$instance = new Registry(new SpecialFactory());
}
return self::$instance;
}
}
Ma classe spéciale est plutôt complexe et grande avec beaucoup d'attributs et d'objets de composition différents. Parce que je ne veux pas lier ma classe spéciale à un backend spécifique, j'allais avoir des Factories différentes pour chaque backend différent (par exemple base de données MySQL ou flux de fichier). Donc, je déplacerais la logique de chargement et d'initialisation vers les usines. Cela ne fonctionnera cependant que si tous les champs de la classe spéciale sont publics à l'usine. Ils ne devraient cependant pas être public pour le reste de l'application.
En C++, je pouvais utiliser des amis pour contourner ce problème. Également ici sur le débordement de pile j'ai lu sur presque le même sujet, mais appliqué à C#. Il a dit que je devrais simplement définir tous les champs publics dans la classe spéciale et que l'usine ne retourne qu'une interface qui expose les méthodes et les attributs que je veux rendre publics à l'application. Mais puisque PHP ne supporte pas l'indication de type return, je ne suis pas capable de retourner uniquement une interface implémentée par la classe Special. Une autre façon que j'ai imaginée serait de faire en sorte que SpecialFactory hérite de la classe Special permettant d'accéder aux champs privés et protégés de l'usine. C'est ce que j'ai appelé "Bastard Factory" puisque l'usine hérite de son propre produit.
Je voudrais savoir si quelqu'un d'entre vous peut trouver un meilleur moyen de réaliser ce que je veux. Ou suis-je complètement hors piste et céder le processus d'initialisation à l'usine est un absolu non-go? Je suis curieux de vos opinions!
J'ai suivi votre suggestion, mais en l'adaptant un peu à PHP qui permet des tableaux associatifs multidimensionnels - qui remplacent plutôt bien SpecialBuilder. Je vous remercie! –