Loading

原型模式

创建型模式对实例化进行抽象,将对象的创建和使用进行分离。外界只需知道对应的公共接口,不需要知道内部的具体实现细节。符合单一职责原则。

原型模式

原型模式(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()
}

参考:

  • 《大话设计模式》 程杰
posted @ 2021-11-25 19:08  JakeLin  阅读(4)  评论(0编辑  收藏  举报