首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >原型设计模式的意义是什么?

原型设计模式的意义是什么?
EN

Stack Overflow用户
提问于 2012-12-15 07:30:42
回答 7查看 24.6K关注 0票数 69

所以我在学校学习设计模式。今天我被告知了“原型”设计模式。

我一定是错过了什么,因为我看不到它的好处。我在网上看到人们说它比使用new更快,但这并不合理;在某些情况下,无论新对象是如何创建的,都需要为其分配内存。

这种模式与“鸡还是蛋”的问题不是在同一个圈子里运行吗?由于原型模式本质上只是克隆对象,因此在某些情况下,原始对象必须自己创建(即不克隆)。这意味着我需要准备好要克隆的每个对象的现有副本。

谁能解释一下这个模式的用法是什么?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2012-12-15 07:34:45

原型模式是一种基于克隆预配置对象的创建模式。这个想法是,您选择一个对象,该对象被配置为默认的或某个特定用例的大致情况,然后克隆该对象并根据您的确切需求进行配置。

当所需的配置很繁重时,该模式对于删除一堆样板代码很有用。我认为原型是一个预设对象,在这里你可以保存一堆状态作为一个新的起点。

票数 33
EN

Stack Overflow用户

发布于 2012-12-15 08:14:20

prototype模式有一些好处,例如:

  • 它消除了初始化object
  • 的(可能昂贵的)开销,它简化并优化了相同类型的多个对象具有大部分相同data

的使用情形

例如,假设您的程序使用的对象是从网络上检索到的大多数不变信息解析出的数据创建的。无需每次创建新对象时检索数据并重新解析它,只要需要新对象,就可以使用原型模式简单地复制原始对象。

另外,假设对象可能具有占用大量内存的数据,例如表示图像的数据。可以通过使用写入时复制样式继承来减少内存,其中显示原始的、未复制的数据,直到代码尝试更改该数据为止。然后,新数据将屏蔽对原始数据的引用。

票数 51
EN

Stack Overflow用户

发布于 2018-06-21 23:34:16

这里的许多其他答案都谈到了克隆已经配置的对象的成本节约,但我想扩展原型模式的另一个“点”。在某些语言中,类被视为一级对象,您可以通过简单地向客户端传递类名来配置客户端在运行时创建的对象类型。在像C++这样的语言中,类不被视为第一类对象,Prototype模式允许您实现相同的效果。

例如,假设我们在一家餐馆有一个Chef,他的工作是制作和提供食物。假设Chef的薪水很低,而且心怀不满,所以他做了如下菜肴:

代码语言:javascript
复制
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...
        }
};

现在,假设我们想要将Chef更改为一个爱炫耀的名厨。这意味着他/她必须在prepareMeal()new不同的菜肴。我们希望修改该方法,以便通过Chef获取new的用餐类型可以指定为参数。在其他语言中,类是第一类对象,我们可以简单地将类名作为参数传递给方法。我们不能在C++中做到这一点,所以我们可以从prototype模式中获益:

代码语言:javascript
复制
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...
        }
};

请注意,clone()方法创建派生类型的实例,但返回指向父类型的指针。这意味着我们可以更改通过使用不同的派生类型创建的对象的类型,而客户端不会知道差异。这种设计现在允许我们配置一个Chef --原型的客户端--在运行时制作不同类型的菜肴:

代码语言:javascript
复制
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);

您可能想知道,通过这种方式,Prototype模式为您购买了与Factory Method模式相同的东西,那么为什么不直接使用它呢?因为工厂方法模式需要一个创建者类的层次结构来反映所创建的产品的层次结构;也就是说,我们需要一个具有make()方法的MozzarellaSticksWithKetchupCreator,一个具有make()方法的HockeyPuckHamburgerWithSoggyFriesCreator,等等。因此,您可以简单地将Prototype模式视为减轻Factory Method模式通常引入的代码冗余的一种方法。

这个论点来自于设计模式:可重用面向对象软件的元素,也就是。“四人帮”这本书。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13887704

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档