Design Patterns - Prototype

Prototype(原型) — 对象创建型模式

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

注意:该模式主要针对于类对象不是一等对象的语言,如C++。而诸如Python这种,该模式没啥用。

适用场景

  1. 当一个系统应该独立于它的产品创建,构成和表示时。
  2. 当要实例化的类是在运行时指定时,例如,通过动态装载。
  3. 为了避免多次创建与产品类层次平行的工厂类层次时。
  4. 当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

效果

Prototype 有许多与 Abstract Factory 和 Builder 一样的效果:它对客户隐藏了具体的产品类,因此减少了客户知道的名字和数目。此外,这些模式使客户无需改变即可使用与特定应用相关的类。

缺点

Prototype 的主要缺陷是每一个 Prototype 的子类都必须实现 Clone 操作,这可能很困难。

UML 图

在这里插入图片描述

示例

class Ball {
 public:
	Ball(){};
	~Ball(){};
	virtual Ball* Clone() const {};
	virtual void Print(){};
};

class BallA : public Ball {
 public:
	BallA();
	BallA(const BallA& other);

	~BallA(){};
	virtual Ball* Clone() const;
	virtual void Print();

 private:
	string _ball_type;
};

BallA::BallA() {
	_ball_type = "ball number one";
}

BallA::BallA(const BallA& other) {
	_ball_type = other._ball_type;
}

Ball* BallA::Clone() const {
	return new BallA(*this);
}

void BallA::Print() {
	cout << _ball_type << endl;
}
class BallB : public Ball {
 public:
	BallB();
	~BallB(){};
	BallB(const BallB&);

	virtual Ball* Clone() const;
	virtual void Print();

 private:
	string _ball_type;
};
BallB::BallB() {
	_ball_type = "ball number two";
}

BallB::BallB(const BallB& other) {
	_ball_type = other._ball_type;
}

Ball* BallB::Clone() const {
	return new BallB(*this);
}

void BallB::Print() {
	cout << _ball_type << endl;
}

class Gun {
 public:
	Gun();
	bool FillBall();
	void UpdateBall(Ball* ball);
	void Shot();

 private:
	Ball* ball[100];
	int now_ball_num;
	Ball* now_ball;
};

Gun::Gun() {
	now_ball_num = 0;
}

bool Gun::FillBall() {
	if (now_ball_num >= 100 || now_ball == NULL) {
		return false;
	}
	ball[now_ball_num++] = now_ball->Clone();
	return true;
}

void Gun::UpdateBall(Ball* ball) {
	now_ball = ball;
}

void Gun::Shot() {
	// cout << now_ball_num << endl;
	for (int i = 0; i < now_ball_num; i++) {
		ball[i]->Print();
	}
}

client

int main() {
	Gun my_gun = Gun();
	BallA ball1 = BallA();
	my_gun.UpdateBall(&ball1);
	my_gun.FillBall();
	my_gun.FillBall();
	my_gun.FillBall();
	BallB ball2 = BallB();
	my_gun.UpdateBall(&ball2);
	my_gun.FillBall();
	my_gun.FillBall();
	my_gun.Shot();
}
/**
 * output:
 * ball number one
 * ball number one
 * ball number one
 * ball number two
 * ball number two
 * /
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值