Une fabrique abstraite encapsule un groupe de fabriques ayant une thématique commune.
Le code client crée une implémentation concrète de la fabrique abstraite, puis utilise les interfaces génériques pour créer des objets concrets de la thématique.
Le client ne se préoccupe pas de savoir laquelle de ces fabriques a donné un objet concret, car il n'utilise que les interfaces génériques des objets produits.
Ce patron de conception sépare les détails d'implémentation d'un ensemble d'objets de leur usage générique.
Un exemple de fabrique abstraite : la classe "documentCreator" fournit une interface permettant de créer différents produits (e.g. "createLetter()" et "createResume()"). Le système a, à sa disposition, des versions concrètes dérivées de la classe "documentCreator", comme par exemple "fancyDocumentCreator" et "modernDocumentCreator", qui possèdent chacune leur propre implémentation de "createLetter()" et "createResume()" pouvant créer des objets tels que "fancyLetter" ou "modernResume". Chacun de ces produits dérive d'une classe abstraite simple comme "Letter" ou "Resume", connues du client. Le code client obtient une instance de "documentCreator" qui correspond à sa demande, puis appelle ses méthodes de fabrication. Tous les objets sont créés par une implémentation de la classe commune "documentCreator" et ont donc la même thématique (ici, ils seront tous "fancy" ou "modern"). Le client a seulement besoin de savoir manipuler les classes abstraites "Letter" ou "Resume", et non chaque version particulière obtenue de la fabrique concrète.
Une fabrique est un endroit du code où sont construits des objets. Le but de ce patron de conception est d'isoler la création des objets de leur utilisation. On peut ainsi ajouter de nouveaux objets dérivés sans modifier le code qui utilise l'objet de base.
Avec ce patron de conception, on peut interchanger des classes concrètes sans changer le code qui les utilise, même à l'exécution. Toutefois, ce patron de conception exige un travail supplémentaire lors du développement initial, et apporte une certaine complexité qui n'est pas forcément souhaitable.
Utilisation.
La "fabrique" détermine le type de l'objet "concret" qu'il faut créer, et c'est ici que l'objet est effectivement créé (dans le cas de C++, Java et C#, c'est l'instruction new). Cependant, la fabrique retourne un pointeur "abstrait" ou une référence "abstraite" sur l'objet concret créé.
Le code client est ainsi isolé de la création de l'objet en l'obligeant à demander à une fabrique de créer l'objet du type abstrait désiré et de lui en retourner le pointeur.
Comme la fabrique retourne uniquement un pointeur abstrait, le code client qui sollicite la fabrique ne connaît pas et n'a pas besoin de connaître le type concret précis de l'objet qui vient d'être créé. Cela signifie en particulier que :
Diagramme de classes UML.
Le patron de conception Fabrique Abstraite peut être représenté par le diagramme UML de classes suivant :
Dans le diagramme ci-dessus, la fabrique abstraite (ou interface) permet de créer des instances de classes dérivées des classes abstraites "ClasseA" et "ClasseB".
Les fabriques concrètes permettent de sélectionner quelles classes concrètes dérivées des classe abstraites "ClasseA" et "ClasseB" sont instanciées.
Exemples.
C++.
/* exemple d'une fabrique abstraite d'eléments d'IHM en C++ */
struct Button
 virtual void paint() = 0;
struct WinButton : public Button
 void paint()
 std::cout « " I'm a window button \n";
};
struct OSXButton : public Button
 void paint()
 std::cout « " I'm a OSX button \n";
};
struct GUIFactory
 virtual Button* createButton() = 0;
struct WinGUIFactory : public GUIFactory
 Button* createButton()
 return new WinButton();
};
struct OSXGUIFactory : public GUIFactory
 Button* createButton()
 return new OSXButton();
};
struct Application
 Application(GUIFactory* factory)
 Button* button = factory->createButton();
 button->paint();
};
/* application : */
int main()
 GUIFactory* factory1 = new WinGUIFactory();
 GUIFactory* factory2 = new OSXGUIFactory();
 Application* winApp = new Application (factory1); 
 Application* osxApp = new Application (factory2);
 delete factory1, factory2;
 return 0;
C#.
/*
 * Exemple : GUIFactory
abstract class GUIFactory
 public static GUIFactory getFactory()
 int sys = readFromConfigFile("OS_TYPE");
 if (sys==0)
 return(new WinFactory());
 else
 return(new OSXFactory());
 public abstract Button createButton();
class WinFactory:GUIFactory
 public override Button createButton()
 return(new WinButton());
class OSXFactory:GUIFactory
 public override Button createButton()
 return(new OSXButton());
abstract class Button
 public string caption;
 public abstract void paint();
class WinButton:Button
 public override void paint()
 Console.WriteLine("I'm a WinButton: "+caption);
class OSXButton:Button
 public override void paint()
 Console.WriteLine("I'm a OSXButton: "+caption);
class Application
 static void Main(string[] args)
 GUIFactory aFactory = GUIFactory.getFactory();
 Button aButton = aFactory.createButton();
 aButton.caption = "Play";
 aButton.paint();
 // affiche :
 // I'm a WinButton: Play
 // ou :
 // I'm a OSXButton: Play
Java.
/*
 * GUIFactory example
public abstract class GUIFactory
 public static GUIFactory getFactory()
 int sys = readFromConfigFile("OS_TYPE");
 if (sys == 0)
 return(new WinFactory());
 else
 return(new OSXFactory());
 public abstract Button createButton();
class WinFactory extends GUIFactory
 public Button createButton()
 return(new WinButton());
class OSXFactory extends GUIFactory
 public Button createButton()
 return(new OSXButton());
public abstract class Button
 private String caption;
 public abstract void paint();
 public String getCaption()
 return caption;
 public void setCaption(String caption)
 this.caption = caption;
class WinButton extends Button
 public void paint()
 System.out.println("I'm a WinButton: "+ getCaption());
class OSXButton extends Button
 public void paint()
 System.out.println("I'm a OSXButton: "+ getCaption());
public class Application
 public static void main(String[] args)
 GUIFactory aFactory = GUIFactory.getFactory();
 Button aButton = aFactory.createButton();
 aButton.setCaption("Play");
 aButton.paint();
 // affiche :
 // I'm a WinButton: Play
 // ou :
 // I'm a OSXButton: Play
Perl.
package GUIFactory;
sub getFactory($$) {
 shift; # skip class
 my $toolkit = shift;
 if ($toolkit eq 'GTK') {
 return(GtkFactory->new);
 } else {
 return(TkFactory->new);
package GtkFactory;
use base 'GUIFactory';
sub new {
 bless({}, shift);
sub createButton {
 return(GtkButton->new);
package TkFactory;
use base 'GUIFactory';
sub new {
 bless({}, shift);
sub createButton() {
 return(TkButton->new);
package Button;
sub new {
 $class = shift;
 my $self = {};
 $self{caption} = ";
 bless($self, $class);
 return $self;
package GtkButton;
use base 'Button';
sub paint() {
 print "I'm a GtkButton\n";
package TkButton;
use base 'Button';
sub paint() {
 print "I'm a TkButton\n";
package main;
my $aFactory = GUIFactory->getFactory;
my $aButton = $aFactory->createButton;
$aButton->{caption} = "Play";
$aButton->paint();
PHP.
/*
 * Fabrique abstraite
abstract class GUIFactory {
 public static function getFactory() {
 $sys = readFromConfigFile("OS_TYPE");
 if ($sys == 0) {
 return(new WinFactory());
 } else {
 return(new OSXFactory());
 public abstract function createButton();
class WinFactory extends GUIFactory {
 public function createButton() {
 return(new WinButton());
class OSXFactory extends GUIFactory {
 public function createButton() {
 return(new OSXButton());
abstract class Button {
 private $_caption;
 public abstract function render();
 public function getCaption(){
 return $this->_caption;
 public function setCaption($caption){
 $this->_caption = $caption;
class WinButton extends Button {
 public function render() {
 return "Je suis un WinButton: ".$this->getCaption();
class OSXButton extends Button {
 public function render() {
 return "Je suis un OSXButton: ".$this->getCaption();
$aFactory = GUIFactory::getFactory();
$aButton = $aFactory->createButton();
$aButton->setCaption("Démarrage");
echo $aButton->render();
// affiche :
// Je suis un WinButton: Démarrage
// ou :
// Je suis un OSXButton: Démarrage
Eiffel.
-- GUI Factory example
class GUI_FACTORY_FOR_CONFIG feature
 get_factory: GUI_FACTORY is
 once
 inspect read_from_config_file("OS_TYPE")
 when 0 then
 create {WIN_FACTORY} Result
 else
 create {OSX_FACTORY} Result
 end
 end
 end
deferred class GUI_FACTORY feature
 create_button: BUTTON is deferred end
end
class WIN_FACTORY inherit GUI_FACTORY feature
 create_button: WIN_BUTTON is do create Result end
end
class OSX_FACTORY inherit GUI_FACTORY feature
 create_button: OSX_BUTTON is do create Result end
end
deferred class BUTTON feature
 caption: STRING
 set_caption(value: like caption) is do caption := value end
 paint is deferred end
end
class WIN_BUTTON inherit BUTTON feature
 paint is do print("I'm a WIN_BUTTON: "+caption+"%N") end
end
class OSX_BUTTON inherit BUTTON feature
 paint is do print("I'm a OSX_BUTTON: "+caption+"%N") end
end
class APPLICATION inherit GUI_FACTORY_FOR_CONFIG creation main feature
 main is local button : BUTTON do
 button := get_factory.create_button
 button.set_caption("Play")
 button.paint
 end
end