Le motif abstract factory
Définition
Ce motif permet la création d’objet par le biais d’une fabrique, qui elle même fera appel a des fabriques dites concrêtes mais sans avoir à les spécifier (c’est là une des différences avec le motif factory).
Principe
Découpler l’objet utilisateur de l’objet fabriquant rend le mode d’instanciation plus souple. On ne se soucie plus de la façon de créer un objet… Le motif fabrication utilise la composition (c’est une autre différence avec le motif factory qui lui préfère l’héritage)
L’exemple par le code
Reprenons l’exemple du motif factory, celui des parseurs.
Nous allons juste ajouter une fabrique abstraite: ParserFactoryCenter
class ParserFactoryCenter
@@factories = []
def ParserFactoryClass.add_factory( p )
@@factories.push( p )
end
def ParserFactoryClass.factories
return @@factories
end
def ParserFactoryClass.parser_for( type )
@@factories.each do |parser_factory|
if parser_factory.type == type
return parser_factory.parser
end
end
return nil
end
end
ParserFactoryClass.add_factory( WikiFactory.new )
ParserFactoryClass.add_factory( HtmlFactory.new )
Nous ajoutons à la fin nos deux fabriques.
Nous pouvons maintenant tester cela. Finalement le grand changement c’est que nous n’avons plus besoin de connaitre la fabrique que nous souhaitons utiliser, c’est l’objet ParserFactoryCenter qui nous fournira ce qu’il nous faut.
Nous sommes même capables de lui demander une liste des parseurs disponibles ! :-)
print "Parseur disponible:" # -> Parseur disponible
ParserFactoryClass.factories.each do |factory|
print factory.type # -> Wiki, HTML
end
wiki_parseur = ParserFactoryClass.parser_for( "Wiki" )
print wiki_parseur # -> #<WikiParser:0xb7c81f04>
print wiki_parseur.parse("source wiki") # -> Je parse très bien le langage wiki
html_parseur = ParserFactoryClass.parser_for( "HTML" )
print html_parseur # -> #<HtmlParser:0xb7c81ec8>
print html_parseur.parse("source html") # -> Je parse très bien le HTML


