Skip to content

Latest commit

 

History

History
133 lines (108 loc) · 3.27 KB

06-原型.md

File metadata and controls

133 lines (108 loc) · 3.27 KB

原型

使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。

UML

  • 抽象原型类(AbstractPrototype):声明克隆clone自身的接口
  • 具体原型类(ConcretedPrototype):实现clone接口
  • 客户端(Client):客户端中声明一个抽象原型类,根据客户需求clone具体原型类对象实例

figure5_prototype

优缺点

  • 优点

    • 当创建新的对象实例较为复杂时,原型模式可以简化创建过程,提高创建对象的效率
    • 可扩展:模式中提供了抽象原型类,具体原型类可适当扩展
    • 创建结构简单:创建工厂即为原型对象本身
  • 缺点

    • 深克隆代码较为复杂
    • 每一个类都得配备一个clone方法,且该方法位于类的内部,修改时违背开闭原则

使用场景

  • 对象之间相同或相似,即只是个别的几个属性不同的时候。
  • 对象的创建过程比较麻烦,但复制比较简单的时候。

用例

盗版书商要盗版一本爆款书A,书的信息有书名及作者信息, 盗版商出于省事和快速, 就直接原封不动的拷贝了原书A, 书名和作者信息一模一样, 后来盗版商发现有被告的风险,于是修改了一些信息

code

// Book.h
#pragma once

#include <string>
#include <iostream>
using namespace std;
struct Author {
	string name;
	string desc;
	Author(string n, string d) {
		this->desc = d;
		this->name = n;
	}
};
class Book {
public:
	Book(const string name, Author* author)
	{
		this->m_author = author;
		this->m_name = name;
	}
	virtual Book* clone() = 0;
	virtual Book* deepClone() = 0;
	inline void printInfo()
	{
		cout << "Book name:" << m_name << "Author:" << m_author->name << "," << m_author->desc << endl;
		cout << "Book author point address:" << m_author << endl;
	}

protected:
	string m_name;
	Author* m_author;
};
// CrazyBook.h
#pragma once
#include "Book.h"
class CrazyBook :
	public Book
{
public:
	CrazyBook(const string name, Author* author);
	CrazyBook(string bookName, string authorName, string authorDesc);
	Book* clone() override;
	Book* deepClone() override;
};
// CrazyBook.cpp
#include "CrazyBook.h"
CrazyBook::CrazyBook(const string name, Author* author) :Book(name, author) {}
CrazyBook::CrazyBook(string bookName, string authorName, string authorDesc) : Book(bookName, new Author(authorName, authorDesc))
{
}
// simple copy
Book* CrazyBook::clone()
{
	Book* copy = new CrazyBook(this->m_name, this->m_author);
	return copy;
}
// deep copy
Book* CrazyBook::deepClone()
{
	string newBookName = "New " + this->m_name;
	Author* newAuthor = new Author("Jack", "A good author");
	Book* copy = new CrazyBook(newBookName, newAuthor);
	return copy;
}
// client.cpp
#include <iostream>
#include "CrazyBook.h"

using namespace std;

int main() {
	Author legalAuthor("Mark", "A famous author");
	Book* legalBook = new CrazyBook("The Letter With Feathers", &legalAuthor);
	cout << "Legal book" << endl;
	legalBook->printInfo();

	Book* copyBook1 = legalBook->clone();
	cout << "Copy1 book" << endl;
	copyBook1->printInfo();
	

	Book* copyBook2 = legalBook->deepClone();
	cout << "Copy2 book" << endl;
	copyBook2->printInfo();

	return 0;
}

result