Ruby: design pattern Abstract Factory

Abstract Factory vs. Factory

La différence entre le design pattern Abstract Factory et Factory est très minime: Factory ne fabrique qu’un type de produit (d’objet) alors qu’Abstract Factory crée des familles de produits, fonctionnellement proches.

Choisir les abstractions

Pour que les abstractions qui sont à la racine de l’arbre représentant la hiérarchie d’héritage demeurent des classes abstraites (simulées, car de telles classes n’existent pas en Ruby), j’y ai placé le constructeur en le forçant à lever une exception pour rendre l’instanciation impossible, ce qui est le propre d’une classe abstraite. Ceci nous force à « répéter » la méthode initialize dans les classes filles, mais ce n’est pas bien grave car le jour où elles seront amenées à différer selon les cas, elles seront déjà isolées dans les bonnes sous-classes. Le but était de rester le plus fidèle possible à ce qu’est ce design pattern, tout en prenant en compte les contraintes du langage.

class ProduitEntretien
  def initialize
      raise "Impossible d'instancier la classe ProduitEntretien"
  end

  def points_vente
    raise NotImplementedError
  end

  attr_reader :caracteristiques
end

class LessiveIndustrielle < ProduitEntretien
  def initialize(caracteristiques)
    @caracteristiques = caracteristiques
  end

  def points_vente
    ['Grande Distribution']
  end
end

class ProduitVaisselleIndustriel < ProduitEntretien
  def initialize(caracteristiques)
    @caracteristiques = caracteristiques
  end

  def points_vente
    ['Grande Distribution']
  end
end

class LessiveEcologique < ProduitEntretien
  def initialize(caracteristiques)
    @caracteristiques = caracteristiques
  end

  def points_vente
    ['Grande Distribution', 'Supérettes Bio', 'Marchés']
  end
end

class ProduitVaisselleEcologique < ProduitEntretien
    def initialize(caracteristiques)
        @caracteristiques = caracteristiques
    end
  def points_vente
    ['Supérettes Bio', 'Marchés']
  end
end

class FabriqueProduitEntretien
  def initialize
    raise "Impossible d'instancier la classe FabriqueProduitEntretien"
  end

  def fabriquer_lessive
    raise NotImplementedError
  end

  def fabriquer_produit_vaisselle
    raise NotImplementedError
  end
end

class FabriqueProduitEntretienEcologique < FabriqueProduitEntretien
  def initialize
    # TODO: à compléter
  end

  def fabriquer_lessive
    LessiveEcologique.new(['tensioactifs' => 'naturels', 'colorants' => 'naturels', 'parfum' => 'huiles essentielles'])
  end

  def fabriquer_produit_vaisselle
    ProduitVaisselleEcologique.new(['base' => 'savon Marseille', 'additifs' => ['soude', 'vinaigre']])
  end
end

class FabriqueProduitEntretienIndustriel < FabriqueProduitEntretien
  def initialize
    # TODO: à compléter
  end

  def fabriquer_lessive
    LessiveIndustrielle.new(['tensioactifs' => 'chimiques', 'colorants' => 'chimiques', 'parfum' => 'synthétiques'])
  end

  def fabriquer_produit_vaisselle
    ProduitVaisselleIndustriel.new(['tensioactifs' => 'chimiques', 'colorants' => 'chimiques', 'parfum' => 'synthétiques'])
  end
end

fabrique_industrielle = FabriqueProduitEntretienIndustriel.new
lessive_industrielle = fabrique_industrielle.fabriquer_lessive
produit_vaisselle_industriel = fabrique_industrielle.fabriquer_produit_vaisselle

fabrique_ecologique = FabriqueProduitEntretienEcologique.new
lessive_ecologique = fabrique_ecologique.fabriquer_lessive
produit_vaisselle_ecologique = fabrique_ecologique.fabriquer_produit_vaisselle

p produit_vaisselle_industriel.points_vente
p produit_vaisselle_ecologique.points_vente

p produit_vaisselle_industriel.caracteristiques
p produit_vaisselle_ecologique.caracteristiques

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *