我正在学习原型设计模式,并被this article sourcemaking上代表的示例搞糊涂了。
class Stooge
{
public:
virtual void slap_stick() = 0;
virtual Stooge* clone() = 0;
};
class Larry : public Stooge
{
public:
void slap_stick()
{
cout << "Larry: poke eyes\n";
}
Stooge* clone() { return new Larry; }
};
class Moe : public Stooge
{
public:
void slap_stick()
{
cout << "Moe: slap head\n";
}
Stooge* clone() { return new Moe; }
};
class Curly : public Stooge
{
public:
void slap_stick()
{
cout << "Curly: suffer abuse\n";
}
Stooge* clone() { return new Curly; }
};
class Factory
{
public:
static Stooge* make_stooge( int choice );
private:
static Stooge* s_prototypes[4];
};
Stooge* Factory::s_prototypes[] = {0, new Larry, new Moe, new Curly};
Stooge* Factory::make_stooge( int choice )
{
return s_prototypes[choice]->clone();
}
int main()
{
vector roles;
int choice;
while (true)
{
cout << "Larry(1) Moe(2) Curly(3) Go(0): ";
cin >> choice;
if (choice == 0)
break;
roles.push_back(Factory::make_stooge( choice ) );
}
for (int i=0; i < roles.size(); ++i)
roles[i]->slap_stick();
for (int i=0; i < roles.size(); ++i)
delete roles[i];
}
根据描述原型设计模式
根据this。原型设计模式是一种设计模式,用于通过复制或克隆现有对象的属性来实例化类。
据我所知,复制类的正常方法是使用复制构造函数,重载operator =或实现克隆函数,通过复制现有对象的所有属性来实例化新对象。
在上面的例子中,我没有看到它是如何通过复制原型来创建新对象,也不是复制构造函数,既不重载operator =,也没有定义适当的克隆函数。
那么我可以假设这不是原型设计模式的实现吗?或许我的假设错了,不明白这个例子?
已编辑:提及@ songyuanyao
在示例中,它新创建新对象,而不复制任何内容
所以我认为上面的例子不是原型模式的合适例子,因为它不代表原型模式的主要目标。
答案 0 :(得分:3)
首先,没有必要克隆一个调用方法的对象,你可能完全有Manager
或Factory
有一个方法来克隆对象,即:
Object Factory::clone( Object &){
}
此外,您可以使用复制构造函数,但复制构造函数的缺点是它仅适用于混凝土类。如果为了良好的设计决策,您只向用户提供对象API(接口/纯虚拟),那么您不能在客户端使用复制构造函数,因此如果预期用途是克隆项目,您可以通过添加{ {1}}方法
Clone
用法:
class BaseVirtualClass{
public:
virtual int foo() = 0;
virtual BaseVirtualClass * clone() = 0;
virtual ~BaseVirtualClass(){}
};
class DerivedClass: public BaseVirtualClass{
int state;
public:
DerivedClass(int a):state(a){}
DerivedClass( const DerivedClass & other)
: state(other.state){}
int foo(){ // override
return state;
}
BaseVirtualClass * clone(){ //override
// I'm using copy constructor here, but hidden from user
return new DerivedClass( *this);
}
};
有时你也想通过工厂做到这一点:
BaseVirtualClass * obj = factory.createObject();
BaseVirtualClass * clone = obj->clone();
注意:除了仅提供指向抽象类的指针外,修复缺少的复制构造函数,BaseVirtualClass * obj = factory.createObject();
BaseVirtualClass * clone = factory.clone(obj);
方法明确意图复制创建Deep Copy的对象状态,无需编写锅炉板代码来重新创建该特定状态下的对象。当创建对象的责任不属于对象时(因为您必须使用具有自定义分配器或其他复杂依赖关系的工厂),则克隆方法将移动到Factory。
修改强>
提问者在互联网上找到的代码示例在我看来是一个边缘案例。 对象在技术上是克隆(它们没有状态,除了类型,因此它们具有相同的状态),但我不认为这是原型模式的一个很好的例子: