Je me suis retrouvé dans une situation en PHP où j'ai besoin d'accéder au constructeur d'une classe sans savoir quelle est la classe. Je pourrais aborder cela d'un mauvais point de vue de conception, donc voici la situation - Je travaille dans Drupal, en écrivant une légère couche OO autour de leur manipulation de données sans classe pour permettre à certains développeurs non-Drupal de se joindre à moi sur un projet.
Dans Drupal, tout le contenu est considéré comme un nœud. J'ai donc créé une classe abstraite - Node. Tout contenu doit avoir un type de contenu spécifique. Avec l'OO, c'est facile - Je crée une classe Personne qui étend Node, ou une classe Événement qui étend Node, etc. Maintenant vient la partie délicate - une partie de mon projet permet à ces nœuds d'être "inclus" dans d'autres nœuds. C'est-à-dire que si le Nœud A inclut le Nœud B, alors chaque fois que A est affiché, les données de B sont affichées. Cela signifie que chaque fois que le Nœud A est instancié, il doit instancier également le Nœud B. MAIS... Node est une classe abstraite. Je ne peux donc pas instancier un Node brut. Je dois instancier l'une de ses classes implémentantes. Donc, autant que je puisse le dire, je dois soit écrire une fonction abstraite et statique que toutes les classes étendues doivent implémenter qui renvoie le constructeur...SOIT, je dois utiliser la réflexion d'une certaine manière pour déterminer le type, et appeler en quelque sorte le constructeur de classe approprié?
Sans tenir compte de Drupal, quelle est la manière la plus appropriée de gérer ce problème d'un point de vue de programmation PHP/OO?
Voici mon code:
title = $node->title;
$this->body = $node->body['und'][0]['safe_value'];
##
## Définir l'URL propre si aliassée
if (drupal_lookup_path('alias', 'node/'.$node->nid)) {
$this->uri = '/'.drupal_lookup_path('alias', 'node/'.$node->nid);
} else {
$this->uri = '/node/'.$node->nid;
}
##
## Définir le résumé court s'il existe, sinon forme courte du texte du corps
if(strlen($node->body['und'][0]['safe_summary'])) {
$this->short_summary = $node->body['und'][0]['safe_summary'];
} else {
$this->short_summary = text_summary($node->body['und'][0]['safe_value'], NULL, 100);
}
##
## Définir le résumé complet à la concaténation du corps
$this->full_summary = text_summary($node->body['und'][0]['safe_value'], NULL, 600);
##
## Ajouter le contenu inclus si le module est activé
if (module_exists('content_inclusion')) {
// est-ce possible? Existe-t-il un meilleur motif de conception disponible?
$this->included_content = Node::get_constructor(node_load($node->content_inclusion['und'][0]['value']));
}
}
public static abstract function get_all_published();
public static abstract function get_by_nid($nid);
public static abstract function get_constructor();
}
?>