Spring SALE
Prototype

Prototype en Ruby

Le Prototype est un patron de conception de création qui permet de cloner des objets - même complexes - sans se coupler à leur classe.

Toutes les classes prototype devraient avoir une interface commune rendant possible la copie des objets, même sans connaître leur classe concrète. Les objets prototype peuvent créer des copies complètes puisqu’ils peuvent accéder aux attributs privés des autres objets de la même classe.

Complexité :

Popularité :

Exemples d’utilisation : Le prototype est prêt à l’emploi dans Ruby avec une interface méthode dup ou clone.

Identification : Le prototype peut facilement être reconnu grâce aux méthodes clone ou copier, etc.

Exemple conceptuel

Dans cet exemple, nous allons voir la structure du Prototype. Nous allons répondre aux questions suivantes :

  • Que contiennent les classes ?
  • Quels rôles jouent-elles ?
  • Comment les éléments du patron sont-ils reliés ?

main.rb: Exemple conceptuel

# The example class that has cloning ability. We'll see how the values of field
# with different types will be cloned.
class Prototype
  attr_accessor :primitive, :component, :circular_reference

  def initialize
    @primitive = nil
    @component = nil
    @circular_reference = nil
  end

  # @return [Prototype]
  def clone
    @component = deep_copy(@component)

    # Cloning an object that has a nested object with backreference requires
    # special treatment. After the cloning is completed, the nested object
    # should point to the cloned object, instead of the original object.
    @circular_reference = deep_copy(@circular_reference)
    @circular_reference.prototype = self
    deep_copy(self)
  end

  # deep_copy is the usual Marshalling hack to make a deep copy. But it's rather
  # slow and inefficient, therefore, in real applications, use a special gem.
  private def deep_copy(object)
    Marshal.load(Marshal.dump(object))
  end
end

class ComponentWithBackReference
  attr_accessor :prototype

  # @param [Prototype] prototype
  def initialize(prototype)
    @prototype = prototype
  end
end

# The client code.
p1 = Prototype.new
p1.primitive = 245
p1.component = Time.now
p1.circular_reference = ComponentWithBackReference.new(p1)

p2 = p1.clone

if p1.primitive == p2.primitive
  puts 'Primitive field values have been carried over to a clone. Yay!'
else
  puts 'Primitive field values have not been copied. Booo!'
end

if p1.component.equal?(p2.component)
  puts 'Simple component has not been cloned. Booo!'
else
  puts 'Simple component has been cloned. Yay!'
end

if p1.circular_reference.equal?(p2.circular_reference)
  puts 'Component with back reference has not been cloned. Booo!'
else
  puts 'Component with back reference has been cloned. Yay!'
end

if p1.circular_reference.prototype.equal?(p2.circular_reference.prototype)
  print 'Component with back reference is linked to original object. Booo!'
else
  print 'Component with back reference is linked to the clone. Yay!'
end

output.txt: Résultat de l’exécution

Primitive field values have been carried over to a clone. Yay!
Simple component has been cloned. Yay!
Component with back reference has been cloned. Yay!
Component with back reference is linked to the clone. Yay!

Prototype dans les autres langues

Prototype en C# Prototype en C++ Prototype en Go Prototype en Java Prototype en PHP Prototype en Python Prototype en Rust Prototype en Swift Prototype en TypeScript