web-dev-qa-db-fra.com

Quel est l'intérêt du modèle de conception Prototype?

Donc, je me renseigne sur les modèles de conception à l'école. Aujourd'hui, on m'a parlé du modèle de conception «Prototype». 

Je dois manquer quelque chose, car je n'en vois pas les avantages. J'ai vu des gens en ligne dire que c'est plus rapide que d'utiliser new, mais cela n'a aucun sens. à un moment donné, quelle que soit la manière dont le nouvel objet est créé, de la mémoire doit lui être allouée. 

Ce schéma ne va-t-il pas dans les mêmes cercles que le problème du «poulet ou de l'œuf»? Puisque le motif Prototype consiste essentiellement en clonage d’objets, l’objet original doit être créé lui-même (c’est-à-dire non cloné). Cela voudrait dire que je devrais avoir une copie existante de chaque objet que je veux cloner déjà prêt à être cloné?

Quelqu'un peut-il expliquer quelle est l'utilisation de ce modèle? 

48
user1905391

Le modèle de prototype est un modèle de création basé sur le clonage d'un objet préconfiguré. L'idée est de choisir un objet configuré pour le cas d'utilisation spécifique ou par défaut d'un cas d'utilisation spécifique, pour ensuite le cloner et le configurer selon vos besoins.

Le modèle est utile pour supprimer un tas de code passe-partout, lorsque la configuration requise serait lourde. Je considère les prototypes comme un objet prédéfini, dans lequel vous enregistrez un groupe d’états en tant que nouveau point de départ.

26
Mark Pauley

Le modèle de prototype présente certains avantages, par exemple:

  • Il élimine la surcharge (potentiellement coûteuse) liée à l'initialisation d'un objet
  • Il simplifie et optimise le cas d'utilisation où plusieurs objets du même type auront essentiellement les mêmes données.

Par exemple, supposons que votre programme utilise des objets créés à partir de données analysées à partir d’informations immuables uniques récupérées sur le réseau. Plutôt que de récupérer les données et de les ré-analyser à chaque fois qu'un nouvel objet est créé, le modèle de prototype peut être utilisé pour simplement dupliquer l'objet d'origine chaque fois qu'un autre est nécessaire.

De plus, supposons que cet objet puisse contenir des données qui consomment de grandes quantités de mémoire, telles que des données représentant des images. La mémoire peut être réduite en utilisant un héritage de style copie sur écriture, dans lequel les données d'origine non dupliquées sont affichées jusqu'à ce que le code tente de les modifier. Ensuite, les nouvelles données seront masquées pour faire référence aux données d'origine.

39
marcus erronius

Beaucoup d'autres réponses ici parlent des économies de coûts du clonage d'un objet déjà configuré, mais je voudrais développer l'autre "point" du motif Prototype. Dans certaines langues, où les classes sont traitées comme des objets de première classe, vous pouvez configurer le type d'objet créé par un client lors de l'exécution en lui transmettant simplement le nom de la classe. Dans des langages tels que C++, où les classes ne sont pas traitées comme des objets de première classe, le modèle Prototype vous permet d'obtenir le même effet.

Par exemple, supposons que nous ayons une Chef dans un restaurant dont la tâche est de préparer et de servir des repas. Disons que la Chef est sous-payée et mécontente, il prépare donc des plats comme celui-ci:

class Chef {
    public:
        void prepareMeal() const {
            MozzarellaSticksWithKetchup* appetizer = new MozzarellaSticksWithKetchup();
            // do something with appetizer...

            HockeyPuckHamburgerWithSoggyFries* entree = new HockeyPuckHamburgerWithSoggyFries();
            // do something with entree...

            FreezerBurnedIceCream* dessert = new FreezerBurnedIceCream();
            // do something with dessert...
        }
};

Maintenant, supposons que nous voulions changer la Chef pour devenir un chef ostentatoire de célébrités. Cela signifie qu'il doit new différents plats dans prepareMeal(). Nous aimerions modifier la méthode afin que les types de repas qui reçoivent new par Chef puissent être spécifiés en tant que paramètres. Dans d'autres langages où les classes sont des objets de première classe, nous pouvons simplement passer les noms de classes en tant que paramètres à la méthode. Nous ne pouvons pas faire cela en C++, nous pouvons donc bénéficier du modèle de prototype:

class Appetizer {
    public:
        virtual Appetizer* clone() const = 0;
        // ...
};

class Entree {
    public:
        virtual Entree* clone() const = 0;
        // ...
};

class Dessert {
    public:
        virtual Dessert* clone() const = 0;
        // ...
};

class MozzarellaSticksWithKetchup : public Appetizer {
    public:
        virtual Appetizer* clone() const override { return new MozzarellaSticksWithKetchup(*this); }
        // ...
};

class HockeyPuckHamburgerWithSoggyFries : public Entree {
    public:
        virtual Entree * clone() const override { return new HockeyPuckHamburgerWithSoggyFries(*this); }
        // ...
};

class FreezerBurnedIceCream : public Dessert {
    public:
        virtual Dessert * clone() const override { return new FreezerBurnedIceCream(*this); }
        // ...
};

// ...and so on for any other derived Appetizers, Entrees, and Desserts.

class Chef {
    public:
        void prepareMeal(Appetizer* appetizer_prototype, Entree* entree_prototype, Dessert* dessert_prototype) const {
            Appetizer* appetizer = appetizer_prototype->clone();
            // do something with appetizer...

            Entree* entree = entree_prototype->clone();
            // do something with entree...

            Dessert* dessert = dessert_prototype->clone();
            // do something with dessert...
        }
};

Notez qu'une méthode clone() crée une instance du type dérivé, mais renvoie un pointeur sur le type parent. Cela signifie que nous pouvons changer le type d'objet créé en utilisant un type dérivé différent et que le client ne saura pas la différence. Cette conception nous permet maintenant de configurer une Chef - le client de nos prototypes - pour créer différents types de plats au moment de l'exécution:

Chef chef;

// The same underpaid chef from before:
MozzarellaSticksWithKetchup mozzarella_sticks;
HockeyPuckHamburgerWithSoggyFries hamburger;
FreezerBurnedIceCream ice_cream;
chef.prepareMeal(&mozzarella_sticks, &hamburger, &ice_cream);

// An ostentatious celebrity chef:
IranianBelugaCaviar caviar;
LobsterFrittataWithFarmFreshChives lobster;
GoldDustedChocolateCupcake cupcake;
chef.prepareMeal(&caviar, &lobster, &cupcake);

Vous vous demandez peut-être que, utilisé de cette manière, le modèle Prototype vous achète la même chose que le modèle Factory Method, alors pourquoi ne pas simplement l'utiliser? Parce que le modèle Factory Method nécessiterait une hiérarchie de classes de créateurs reflétant la hiérarchie de produits en cours de création; c'est-à-dire que nous aurions besoin d'une MozzarellaSticksWithKetchupCreator avec une méthode make(), d'une HockeyPuckHamburgerWithSoggyFriesCreator avec une méthode make() et ainsi de suite. Par conséquent, vous pouvez considérer le modèle Prototype simplement comme un moyen d’alléger la redondance du code souvent introduite par le modèle Méthode d'usine.

Cet argument est tiré de Patterns de conception: éléments d'un logiciel orienté objet réutilisable , a.k.a., le livre "Gang of Four".

2
Ethan Hearne

Si vous souhaitez créer un objet mais ne souhaitez pas suivre la procédure coûteuse de création d'objet où des appels réseau ou de base de données sont effectués, utilisez le modèle prototype. Créez simplement une copie de l'objet et apportez vos modifications.

1
user2328970

Si vous avez une exigence, où vous devez remplir ou utiliser les mêmes données contenant Object repeatable

et 

il n'est pas possible de construire à partir d'un objet existant, par exemple [Construire un objet à l'aide de Network Stream] ou

construire un objet prend beaucoup de temps [Construire un gros objet en récupérant les données de la base de données] puis utiliser ce modèle de conception, car dans ce cas, une copie de l'objet existant est créée, cette copie serait différente de l'objet d'origine et pourrait être utilisée tout comme l'original. 

0
Andy

Par rapport au modèle de fabrique abstraite, en utilisant le modèle de prototype, vous n'avez pas besoin d'une grande hiérarchie de fabriques, mais simplement d'une grande hiérarchie de produits.

0
Michael Zheng