原型模式
创建型模式对实例化进行抽象,将对象的创建和使用进行分离。外界只需知道对应的公共接口,不需要知道内部的具体实现细节。符合单一职责原则。
原型模式
原型模式(Prototype Pattern):它属于类创建型模式。复制已有对象, 而又无需使代码依赖它们所属的类。简单说就是对象拷贝,原型类声明一个克隆自身的接口,具体原型类均实现该接口方法。
原型模式实现的是一个Clone 接口,注意是接口,也就是基于多态的 Clone 虚函数。也就是说原型模式能够通过基类指针来复制派生类对象。拷贝构造函数完不成这样的任务。在继承场景下,Clone 函数可以定义为虚函数。 ------ 知乎
实例:秋招投简历,准备好一份简历,去打印(克隆)出多份纸质简历。
C++代码示例
/**
* 原型类,声明一个克隆自身的接口
*/
class Prototype {
public:
virtual ~Prototype() = default;
virtual void display() = 0;
virtual Prototype *clone() = 0;
};
/**
* 具体原型类,实现克隆自身的接口
*/
class Resume : public Prototype {
public:
Resume() = default;
Resume(const Resume &resume) {
this->name = resume.name;
this->sex = resume.sex;
this->age = resume.age;
}
void setPersonalInfo(string name, string sex, int age) {
this->name = name;
this->sex = sex;
this->age = age;
}
void display() override {
cout << "====== Resume ======" << endl;
cout << "\tname : " << name << endl;
cout << "\tsex : " << sex << endl;
cout << "\tage : " << age << endl;
}
// 克隆
Prototype *clone() override {
return new Resume(*this);
}
private:
string name;
string sex;
int age{};
// ...
};
// 测试
int main() {
Resume resumeA;
resumeA.setPersonalInfo("ZhangSan", "male", 18);
cout << "print resumeA" << endl;
resumeA.display();
cout << endl;
Prototype *p1 = resumeA.clone();
cout << "print first clone resume" << endl;
p1->display();
cout << endl;
// 通过基类指针来复制派生类对象
Prototype *p2 = p1->clone();
cout << "print second clone resume" << endl;
p2->display();
cout << endl;
return 0;
}
Go代码示例
// 原型类,声明一个克隆自身的接口
type Prototype interface {
Display()
Clone() Prototype // 克隆接口
}
// 具体原型类,实现克隆自身的接口
type Resume struct {
name string
sex string
age int64
}
func (r *Resume) Display() {
fmt.Println("====== Resume ======")
fmt.Println("\tname : " + r.name)
fmt.Println("\tsex : " + r.sex)
fmt.Println("\tage : " + strconv.FormatInt(r.age, 10))
}
func (r *Resume) Clone() Prototype {
return &Resume{
name: r.name,
sex: r.sex,
age: r.age,
}
}
// 测试
func TestClone(t *testing.T) {
resume := Resume{
name: "ZhangSan",
sex: "male",
age: 18,
}
fmt.Println("print resume")
resume.Display()
fmt.Println()
cp := resume.Clone()
fmt.Println("print clone resume")
cp.Display()
fmt.Println()
}
参考:
- 《大话设计模式》 程杰