11
votes

Comment puis-je coder une usine à Perl et à Moose?

y a-t-il un moyen plus simple ou meilleur (=> plus facile à maintenir) d'utiliser Perl et orose code > pour instancier les classes basées sur des données entrantes?

Le code suivant est un échantillon dûment dépouillé d'un projet que je travaille sur. p> xxx pré>

P>

__DATA__
Foo, First Case
Bar, Second Case


0 commentaires

5 Réponses :


5
votes

Vous pouvez simplement faire: xxx

si cela est plus facile ou mieux à vous de décider.


4 commentaires

En utilisant une variable comme la classe à être instanciée $ cas-> nouvelle (..) de cette façon se sent très étrange. Mais oui, extrêmement compact, par rapport à mon code (où je l'épelle bénis ({}, $ cas) Merci pour la pointe!


Pourquoi est-ce étrange? Un nom de classe à Perl est juste une chaîne. Foo-> bla est exactement la même chose que "foo" -> bla.


S'il n'y a pas de logique en usine pour choisir la sous-classe correcte pour instancier, ce n'est pas une grande partie d'une usine et que ceci est par une large marge la meilleure solution.


Mon code d'origine (trop long pour poster, donc je l'ai dépassé à l'échantillon ci-dessus) une requête de DB et utilise une certaine logique dérive la classe qui doit être instanciée. Je veux encapsuler cela dans une usine.



4
votes

Eh bien, l'objet est déjà créé lorsque Build code> est appelé, alors je dirais

sub BUILD {
      my $self = shift;
      return bless $self, $self->SUBCLASS;
}


2 commentaires

Où m'enverriez-vous pour apprendre / comprendre la transition de "héritage basé" à "basé sur le rôle"?


Le manuel d'orignal sur les rôles serait un démarrage Search.cpan.org/perldoc/moose :: Manuel :: Rôles



10
votes

ick. Stevan a un argument très convaincant que nouveau code> devrait toujours seulement renvoyer une instance de classe. Tout ce que d'autre est confus aux nouvelles personnes apprenant le système.

Vous voudrez peut-être jeter un oeil à Moosex :: AbstractFactory . Si cela ne fonctionnera pas pour vous, alors: P>

package Foo;
use Moose;
with qw(MooseX::Traits);

package Bar;
use Moose;
with qw(MooseX::Traits);

package Messaging;
use Moose::Role;

has msg => ( is => 'ro', required => 1);

sub Hi {
   my $self = shift;
   print "Hi, I'm a " . ref($self)  ." and I say [". $self->MSG()."]\n";
}

package main;
use strict;
Foo->with_traits('Messaging')->new( msg => 'First Case')->Hi;


3 commentaires

a [qw (Sous-classe msg)] => (is => 'ro', requis => 1); truc neat .. mais "nontuitive" pour quiconque n'est pas familier avec Perl ..


Non ce n'est pas. Cela fait partie de l'API de Moose et n'a rien à voir avec Perl. (Si vous vouliez être inintervalu, vous écririez "a $ _ => (...) pour qw / sous-classe msg /". Mais bien sûr, tout le monde sait que cela aussi.)


Je pense qu'il est prudent d'assumer quiconque qui lise une question sur Moose soit familiarisé avec Perl ou souhaite être. Cette syntaxe est documentée à Moose.pm et ils sont libres de poser à ce sujet.



5
votes

Juste une note sur certaines des réponses:

appeler bénisse dans la construction ou n'importe où à l'extérieur de la MOP interne, est toujours inacceptable. (Si vous devez envahir, il y a Classe :: MOP :: Classe-> Rebless_instance !)

I Deuxièmement, les conseils de ne pas autoriser Nouveau à Renvoie autre chose qu'une instance de __ package __ . Si vous voulez une méthode qui crée une instance de quelque chose, appelez-la autre chose. Exemple: xxx

puis, lorsque vous souhaitez créer un message littéral: xxx

Quand vous voulez analyser une chaîne et renvoyer la sous-classe de message correcte: xxx

Enfin, s'il n'a pas de sens de pouvoir créer une instance de message, il ne faut pas être une classe. Cela devrait être un rôle.

Vous pouvez gérer le bâtiment avec un autre objet, bien sûr. Assurez-vous simplement que cet autre objet n'est responsable que pour comprendre le format de la chaîne, par exemple, et non des messages internes: xxx

Vous n'êtes plus préoccupé par une "superclasse" Responsable du bâtiment "Sous-classes", qui, à mon avis, est une meilleure conception. (N'oubliez pas que la messagestring n'a pas de pouvoir spécial sur les classes qui font "message". C'est la clé ici; il est uniquement responsable de la compréhension des messages stricts.)

Quoi qu'il en soit, maintenant, vous venez de: xxx

(vous savez "MVC"? Ceci est similaire.)


0 commentaires

3
votes

Utilisez simplement un autre objet d'usine pour construire des objets de cette classe.

Plus simple, plus flexible, plus fiable, etc.

My $ usine = usine-> neuf (... paramètres d'usine ...);

mon objet $ objet = $ usine-> new_Object (... divers paramètres ...);

new_object peut analyser les paramètres et prendre des décisions sur les deux données à l'intérieur $ usine et les données de ces paramètres.

Lorsque vous comprenez que vous aurez besoin d'objets codependants à l'étape suivante, recherchez une inversion de la structure de contrôle.


0 commentaires