精华内容
下载资源
问答
  • 原型模式介绍,包括应用场景,优缺点,模式结构,类图 以及 C++代码示例

    更多设计模式参看: 设计模式之模式概述(模式汇总)(C++实现)

    介绍

    原型模式(Prototype Pattern)是用于创建重复的对象,同时又能保证性能。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

    这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

    意图:

    原型模式(Prototype Pattern): 使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。从一个对象再创建另外一个可定制的对象,而且不需要知道任何创建的细节。

    解决问题:

    在运行期建立和删除原型。

    实现概述:

    利用已有的一个原型对象,快速地生成和原型对象一样的实例。

    要点:

    1、实现克隆操作,也就是 clone()

    2、能够隔离类对象的使用者和具体类型之间的耦合关系,要求这些具体类型拥有稳定的接口。

    应用场景:

    (1) 创建新对象成本较大(如一些初始化需要较长时间,占用太多的CPU资源或网络资源),并且新的对象可以通过原型模式对已有对象进行复制来获得,如有必要可稍作修改。

    (2) 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。

    生活中场景

    细胞分裂;克隆羊;抄作业

    软件中场景

    JAVA 中的 Object clone() 方法;工作周报、绩效 、邮件等拷贝上次

    优点:

    (1) 当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,提高新实例的创建效率。

    (2) 扩展性较好,模式中提供了抽象原型类,具体原型类可根据需要扩展。

    (3) 原型模式提供了简化的创建结构,模式中产品的复制是通过封装在原型类中的克隆方法实现的,无须专门的工厂类来创建产品。

    缺点:

    (1) 需要为每一个类配备一个克隆方法,该克隆方法位于一个类的内部,改造已有类时需要修改源代码,违背开闭原则;

    (2) 在实现深克隆时需要编写较为复杂的代码,并且如果对象嵌套很多引用时,为了实现深拷贝每一层嵌套都必须支持深克隆。

    深拷贝与浅拷贝

    浅拷贝:只是增加了一个指针指向已存在的内存地址,如果原地址发生改变,那么浅拷贝出来的对象也会相应的改变。相当于一个箱子有多个钥匙,其中某人打开箱子取走箱子里的东西时,其他人再打开箱子看到的都是空箱子。

    深拷贝:是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存。相当有多个箱子每个箱子对应一个钥匙,一个人取走他的钥匙对应的箱子里的东西时,不会对其他人产生影响。

    模式结构

    角色

    • 抽象原型类(AbstractPrototype):规定了具体原型对象必须实现的接口(如果要提供深拷贝,则必须具有实现clone的规定)
    • 具体原型类(ConcretePrototype):从抽象原型派生而来,是客户程序使用的对象,即被复制的对象,需要实现抽象原型角色所要求的接口。
    • 客户端(Client):客户端中声明一个抽象原型类,根据客户需求clone具体原型类对象实例

    类图

    在这里插入图片描述

    代码示例

    在已有邮件上修改生成需要发送的新邮件

    GitHub

    Prototype

    抽象原型类(AbstractPrototype)

    /// 抽象原型类(AbstractPrototype)
    class AbstractPrototypeMail {
    public:
        virtual ~AbstractPrototypeMail() = default;
        virtual AbstractPrototypeMail *clone() = 0;
        virtual void showMail() = 0;
        virtual void changeTitle(std::string title) = 0;
        virtual void changeSender(std::string sender) = 0;
        virtual void changeRecipients(std::string rec) = 0;
        virtual void changeBody(std::string body) = 0;
        virtual void changeAtt(std::string name) = 0;
    protected:
        AbstractPrototypeMail() = default;
    };
    

    具体原型类(ConcretePrototype)

    /// 具体原型类(ConcretePrototype)
    class ConcretePrototypeMail : public AbstractPrototypeMail {
    public:
        ConcretePrototypeMail(const std::string &title,const std::string &sender,const std::string &rec,const std::string &body, const std::string &nameAtt=""){
            std::cout << "ConcretePrototypeMail Hello" << std::endl;
            mailTitle = title;
            mailSender = sender;
            mailRecipients = rec;
            mailBody = body;
            if (!nameAtt.empty()) {
                mailAtta = new Attachment();
                mailAtta->changeName(nameAtt);
            }
        }
        ~ConcretePrototypeMail() override {
            std::cout << "ConcretePrototypeMail Bye" << std::endl;
            if (mailAtta!= nullptr) {
                delete(mailAtta);
            }
        }
        AbstractPrototypeMail *clone() override {
            auto *newMail = new ConcretePrototypeMail(mailTitle,mailSender,mailRecipients,mailBody,mailAtta->getName());
            return newMail;
        }
        void showMail() override {
            std::cout << "MailTitle: " << mailTitle << std::endl;
            std::cout << "MailSender: " << mailSender << std::endl;
            std::cout << "MailRecipients: " << mailRecipients << std::endl;
            std::cout << "MailBody: " << mailBody << std::endl;
            std::cout << "MailAttachment: " << mailAtta->getName() << std::endl;
    
        }
        void changeTitle(const std::string title) override {
            mailTitle = title;
        }
        void changeSender(const std::string sender) override {
            mailSender = sender;
        };
        void changeRecipients(const std::string rec) override {
            mailRecipients = rec;
        }
        void changeBody(const std::string body) override {
            mailBody = body;
        }
        void changeAtt(const std::string name) override  {
            if (mailAtta!= nullptr) {
                delete(mailAtta);
            }
            mailAtta = new Attachment();
            mailAtta->changeName(name);
        }
    
    private:
        std::string mailTitle;
        std::string mailSender;
        std::string mailRecipients; /// 按理说 收件人应该有多个 可改为list等其他数据结构,这里采用std::string用于演示
        std::string mailBody;
        Attachment *mailAtta = nullptr;
    };   
    

    附件类

    /// 附件类
    class Attachment {
    public:
        Attachment() {
            std::cout << "Attachment Hello" << std::endl;
        }
        ~Attachment() {
            std::cout << "Attachment Bye" << std::endl;
        }
        void changeName(const std::string &name) {
            nameAtt = name;
        };
        std::string getName() {
            return nameAtt;
        }
    private:
        std::string nameAtt; /// 附件名
    };
    

    测试

    浅拷贝:

    
    int main() {
        /// 用于复用的初始邮件创建
        auto *originalMail = new ConcretePrototypeMail("original_title","original_sender","original_rec","original_body","original_attachment");
        std::cout << "originalMail address: "<< originalMail << std::endl;
        originalMail->showMail();
        /// 浅拷贝
        std::cout << "====浅拷贝====" << std::endl;
        auto *copyMail_A = originalMail;
        copyMail_A->changeTitle("copymail_title");
        copyMail_A->changeSender("copymail_sender");
        copyMail_A->changeRecipients("copymail_rec");
        copyMail_A->changeBody("copymail_body");
        copyMail_A->changeAtt("copymail_attachment");
        std::cout << "====copyMail_A====" << std::endl;
        std::cout << "copyMail_A address: "<< copyMail_A << std::endl;
        copyMail_A->showMail();
        std::cout << "====originalMail====" << std::endl;
        originalMail->showMail();
        delete originalMail;
        return 0;
    }
    

    originalMail的数据也同样被修改了

    深拷贝:

    int main() {
        /// 用于复用的初始邮件创建
        auto *originalMail = new ConcretePrototypeMail("original_title","original_sender","original_rec","original_body");
        originalMail->changeAtt("original_attachment"); 
        std::cout << "originalMail address: "<< originalMail << std::endl;
        originalMail->showMail();
        /// 深拷贝
        std::cout << "====深拷贝====" << std::endl;
        auto *copyMail_A = originalMail->clone();
        copyMail_A->changeTitle("copymail_title");
        copyMail_A->changeSender("copymail_sender");
        copyMail_A->changeRecipients("copymail_rec");
        copyMail_A->changeBody("copymail_body");
        copyMail_A->changeAtt("copymail_attachment");
        std::cout << "====copyMail_A====" << std::endl;
        std::cout << "copyMail_A address: "<< copyMail_A << std::endl;
        copyMail_A->showMail();
        std::cout << "====originalMail====" << std::endl;
        originalMail->showMail();
        delete originalMail;
        delete copyMail_A;
        return 0;
    }
    

    输出

    浅拷贝输出:
    在这里插入图片描述

    深拷贝输出:

    在这里插入图片描述

    个人能力有限,如有错误之处或者其他建议,敬请告知欢迎探讨,谢谢!

    展开全文
  • 文章目录1 原型模式2 代码实现3 用指针,不直接使用对象 1 原型模式 原型模式其实就是从一个对象再创建另外一个可定制对象,而且不需要知道任何创建的细节。 假设有一个简历,需要针对不同的公司修改其中的投递意向...

    1 原型模式

    原型模式其实就是从一个对象再创建另外一个可定制对象,而且不需要知道任何创建的细节。

    假设有一个简历,需要针对不同的公司修改其中的投递意向,在创建简历的时候,其他信息都不变,就一个内容不一样,如果针对不同的简历创建不同的实例,则每次创建简历都需要对其中的初始化参数进行赋值,并不是一个比较优质的解决方案。此时可以采用原型模式。

    2 代码实现

    //CommunicateStruct.h
    #pragma once
    
    #include <string>
    using namespace std;
    class CommunicateStruct
    {
    public:
    	CommunicateStruct(int ,int );
    	~CommunicateStruct(void);
    
    	void setCompany(string);
    
    
    
    	int m_id;
    	int m_age;
    	string m_company;
    };
    
    
    
    //CommunicateStruct.cpp
    #include "StdAfx.h"
    #include "CommunicateStruct.h"
    
    
    CommunicateStruct::CommunicateStruct(int id,int age)
    {
    	m_id  = id;
    	m_age = age;
    	
    }
    void CommunicateStruct::setCompany(string name)
    {
    	m_company = name;
    }
    
    
    CommunicateStruct::~CommunicateStruct(void)
    {
    }
    
    

    在我们的main函数中,实现三份简历的方法:

    // Prototype.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "CommunicateStruct.h"
    #include <iostream>
    
    using namespace std;
    int _tmain(int argc, _TCHAR* argv[])
    {
    	CommunicateStruct p(0,18);
    	p.setCompany("a");
    	CommunicateStruct t = p;
    	t.setCompany("b");
    	CommunicateStruct y = p;
    	y.setCompany("c");
    	
    	cout<<p.m_id<<" "<<p.m_age<<" "<<p.m_company<<endl;
    	cout<<t.m_id<<" "<<t.m_age<<" "<<t.m_company<<endl;
    	cout<<y.m_id<<" "<<y.m_age<<" "<<y.m_company<<endl;
    
    
    	int instring;
    	cin>>instring;
    
    	return 0;
    }
    

    可以看到,该方法可以实现快速创建3分简历,而且只是修改一下公司的名字即可。

    3 用指针,不直接使用对象

    事实上,我们c++上通常会遇到一些情况,导致我们需要用指针定义对象:
    (1)传参的需要
    (2)多态的需求
    (3)前向声明,不需要立即创建对象,解耦的需要
    如果直接把上面改成指针:

    	CommunicateStruct *p = new CommunicateStruct(0,18);
    	p->setCompany("a");
    	CommunicateStruct *t = p;
    	t->setCompany("b");
    	CommunicateStruct *y = p;
    	y->setCompany("c");
    	
    	cout<<p->m_id<<" "<<p->m_age<<" "<<p->m_company<<endl;
    	cout<<t->m_id<<" "<<t->m_age<<" "<<t->m_company<<endl;
    	cout<<y->m_id<<" "<<y->m_age<<" "<<y->m_company<<endl;
    

    这样很明显是错的,此时需要创建一个Clone函数。

    CommunicateStruct *CommunicateStruct::Clone()
    {
    	return new CommunicateStruct(m_id,m_age);
    }
    

    而使用的时候,Clone一下即可。

    	CommunicateStruct *p = new CommunicateStruct(0,18);
    	p->setCompany("a");
    	CommunicateStruct *t = p->Clone();
    	t->setCompany("b");
    	CommunicateStruct *y  = p->Clone();
    	y->setCompany("c");
    
    展开全文
  • 举个例子来介绍原型模式,在找工作的时候,我们需要准备简历,假设没有打印设备,我们需要手写多份简历,这些简历的内容都是一样的,这样有个缺陷,如果想要修改简历中的某项,那么所有已经写好的简历都需要修改,...

    原型模式提供了自我复制的功能,就是说新对象的创建可以通过已有的对象进行创建。用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。其中有一个词很重要,那就是拷贝。可以说,拷贝是原型模式的精髓所在。

    举个例子来介绍原型模式,在找工作的时候,我们需要准备简历,假设没有打印设备,我们需要手写多份简历,这些简历的内容都是一样的,这样有个缺陷,如果想要修改简历中的某项,那么所有已经写好的简历都需要修改,工作量很大,随着科技的进步,出现了打印设备。我们只需要手写一份,然后利用打印设备复印多份即可。如果要修改简历中的某项,那么修改原始版本就可以,然后再复印。原始的那份手稿相当于一个原型,有了它,通过复印(拷贝)创造出更多的新简历。这就是原型模式的基本思想。

    原型模式实现的关键就是Clone函数,对于C++来说,其实就是拷贝构造函数,需实现深拷贝。

    #include<iostream>
    #include<string>
    using namespace std;
    //父类
    class Resume
    {
    protected:
    	char *name;
    public:
    	Resume(){}
    	virtual ~Resume(){}
    	virtual Resume* Clone(){return NULL;}
    	virtual void Set(const char *n){}
    	virtual void Show(){}
    };
    
    class ResumeA :public Resume
    {
    public:
    	ResumeA(const char* str);    //构造函数
    	ResumeA(const ResumeA& r);   //拷贝构造函数
    	~ResumeA();  //析构函数
    	ResumeA* Clone(); //克隆 关键所在
    	void Set(const char *n);
    	void Show();
    };
    
    ResumeA::ResumeA(const char *str)
    {
    	if(str == NULL){
    		name = new char[1];
    		name[0] = '\0';
    	}
    	else
    	{
    		name = new char[strlen(str)+1];
    		strcpy(name,str);
    	}
    }
    ResumeA::~ResumeA()
    {
    	delete []name;
    }
    
    ResumeA::ResumeA(const ResumeA& r)
    {
    	name = new char[strlen(r.name)+1];
    	strcpy(name,r.name);
    }
    ResumeA* ResumeA::Clone(){
    	return new ResumeA(*this);
    }
    void ResumeA::Set(const char *n)
    {
    	if(strlen(n)<=strlen(name))
    	{
    		strcpy(name,n);
    	}
    	else
    	{
    		name = new char[strlen(n)+1];
    		strcpy(name,n);
    	}
    }
    
    void ResumeA::Show()
    {
    	cout<<"ResumeA name:"<<name<<endl;
    };
    
    int main()
    {
    	Resume *r1 = new ResumeA("A");
    
    	Resume *r2 = r1->Clone(); //A
    	Resume *r3 = r1->Clone(); //A
    	Resume *r4 = r1->Clone(); //A
    
    	delete r1;  delete r2;
    	r1 = NULL;   r2 = NULL;
    
    	r3->Show(); //A
    	r4->Show(); //A
    	
    
    	r3->Set("ML");
    	r3->Show(); //ML
    	Resume *r5 = r3->Clone();
    	r4->Show(); //A
    	r5->Show();  //ML
    
    	delete r3;  delete r4;  delete r5;  
    	r3 = NULL;   r4 = NULL; r5 = NULL;   
    
    	return 0;
    }
    
    

    在这里插入图片描述

    原型模式要解决的问题就是不用重新初始化对象,而是动态地获取对象运行时的状态,你只需要对对象做部分属性或行为的修改即可。简化对象的创建,无需理会创建过程。

    其中部分内容参考于:https://blog.csdn.net/wuzhekai1985/article/details/6667020

    展开全文
  • 设计模式-原型模式

    2021-05-20 17:24:51
    设计模式-原型模式

    原型模式

    其它创建型模式链接:

    1. 设计模式-简单工厂模式
    2. 设计模式-工厂方法模式
    3. 设计模式-抽象工厂模式
    4. 设计模式-单例模式
    5. 设计模式-建造者模式

    1.原型模式概述

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

    原型模式是一种对象创建型模式,它的工作原理很简单:将一个原型对象传给要发动创建的(即客户端对象),这个要发动创建的对象通过请求原型对象复制自己来实现创建过程。由于在软件系统中经常会遇到创建多个相同或相似对象的情况,因此原型模式在实际开发中有较高的使用频率。原型模式是一种另类的创建型模式,创建新对象的工厂就是原型类本身,工厂方法由负责原型对象的克隆方法来实现。

    需要注意的是通过克隆方法所创建的对象是全新对象,它们在内存中拥有全新的地址,通常对克隆所产生的对象进行修改不会对原型对象造成任何影响,每个克隆对象都是相互独立的。通过不同的方式对克隆对象进行修改后,可以得到一系列相似但不完全相同的对象。

    2.原型模式结构

    image-20210520110403133

    原型模式包含三个角色:

    1. Prototype(抽象原型类):它是声明克隆方法的接口,是所有具体原型类的公共父类,它可以是抽象类也可以是接口,甚至还可以是具体实现类。
    2. ConcretePrototype(具体原型类):它实现在抽象原型类中声明的克隆方法,在克隆方法中返回一个自己的一个克隆对象。
    3. Client(客户类):在客户类中,让一个原型对象克隆自身从而创建一个新的对象,只需要直接实例化或通过工厂方法等方式创建一个原型对象,再通过调用该对象的克隆方法即可得到多个相同的对象。由于客户端针对抽象原型类Prototype编程,因此用户可以根据需要选择具体原型类,系统具有较好的可扩展性,增加或者更换都很方便。

    3.浅克隆与深克隆

    3.1浅克隆

    在浅克隆中,如果原型对象的成员变量为值类型(int,double,byte等),将复制一份给克隆对象;如果原型对象的成员变量是引用类型(类,接口,数组等),则将引用对象的地址复制一份给克隆对象,也就是说原型对象和成员变量指向相同的内存地址。

    image-20210520115239712

    3.2深克隆

    在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。

    image-20210520143612587

    4.案例

    在使用某OA系统时,有些岗位的员工发现他们每周的工作都大同小异,因此在填写工作周报时很多内容都是重复的,为了提高工作周报的效率,大家迫切希望有一种机制能够快速创建相同或相似的周报,包括创建周报的附件。

    使用原型模式对该OA系统中的工作周报创建模块进行改进。

    4.1结构图

    image-20210520145004211

    4.2代码实现

    Attachment:附件类

    @Data
    public class Attachment {
        private String name;
    
        public void download() {
            System.out.println("下载附件,文件名为" + name);
        }
    }
    

    WeeklyLog:工作周报类

    @Data
    public class WeeklyLog implements Cloneable {
        private Attachment attachment;
        private String name;
        private String date;
        private String content;
    
        @Override
        public WeeklyLog clone() {
            Object obj;
            try {
                obj = super.clone();
                return (WeeklyLog) obj;
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
                return null;
            }
        }
    }
    

    Client:客户端类

    public class Client {
        public static void main(String[] args) {
            WeeklyLog log_previous,log_new;
            log_previous=new WeeklyLog();
            Attachment attachment=new Attachment();
            attachment.setName("附件一");
            log_previous.setAttachment(attachment);
            log_new=log_previous.clone();
            //比较周报
            System.out.println("周报是否相同?:"+(log_previous==log_new));
            //比较附件
            System.out.println("附件是否相同?:"+(log_previous.getAttachment()==log_new.getAttachment()));
        }
    }
    

    结果展示

    周报是否相同?:false
    附件是否相同?:true

    5.深克隆解决方案

    在java语言中可以通过序列化等方式来实现深克隆,写到流中的对象是原有对象的一个复制,而原对象仍然存在内存中。不仅可以复制对象本身,还可以复制其引用的成员变量。

    需要注意复制的类必须实现Serializable接口。

    5.1结构图

    image-20210520145217596

    5.2Attachment:附件类

    @Data
    public class Attachment implements Serializable {
        private String name;
    
        public void download() {
            System.out.println("下载附件,文件名为" + name);
        }
    }
    

    5.3WeeklyLog:工作周报类

    @Data
    public class WeeklyLog implements  Serializable {
        private Attachment attachment;
        private String name;
        private String date;
        private String content;
    
        public WeeklyLog deepClone() throws IOException, ClassNotFoundException {
            ByteArrayOutputStream bao = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bao);
            oos.writeObject(this);
            ByteArrayInputStream bis = new ByteArrayInputStream(bao.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            return (WeeklyLog) ois.readObject();
        }
    }
    

    5.4Client:客户端类

    public class Client {
        public static void main(String[] args) {
            WeeklyLog log_previous,log_new;
            log_previous=new WeeklyLog();
            Attachment attachment=new Attachment();
            attachment.setName("附件一");
            log_previous.setAttachment(attachment);
            try {
                log_new=log_previous.deepClone();
            } catch (IOException | ClassNotFoundException e) {
                log_new=null;
                e.printStackTrace();
            }
            //比较周报
            System.out.println("周报是否相同?:"+(log_previous==log_new));
            //比较附件
            System.out.println("附件是否相同?:"+(log_previous.getAttachment()==log_new.getAttachment()));
        }
    }
    

    5.5结果展示

    周报是否相同?:false
    附件是否相同?:false

    6.原型模式优缺点与适用环境

    6.1原型模式优点

    原型模式优点如下:

    1. 当创建对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过复制一个已有的实例可以提高新实例的创建效率。
    2. 扩展性好,由于在原型模式中提供了抽象原型类,在客户端可以针对抽象原型类进行编程,而将具体原型类写在配置文件中,增加或减少产品类对原有系统没有任何影响。
    3. 原型模式提供了简化的创建结构,工厂方法模式常常需要有一个与产品类等级结构相同的工厂等级结构,而原型模式就不需要这样搞,原型模式中产品的复制是通过封装在原型类中的克隆方法实现的,无需专门的工厂类来创建产品。
    4. 可以使用深克隆的方式保存对象的状态,使用原型模式将对象复制一份并将其状态保存起来,以便在需要的时候使用(例如恢复到某一历史状态),可以辅助实现撤销操作。

    6.2原型模式缺点

    原型模式缺点如下:

    1. 需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部,当对已有的类进行改造时需要修改源代码,违背了开闭原则。
    2. 在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来可能会比较复杂。

    6.3原型模式适用环境

    在以下情况下可以考虑使用原型模式:

    1. 创建新对象成本较大(例如要占用较长时间、占用太多CPU资源等),新对象可以通过复制已有对象来获得,如果是相似对象,则可以对其成员变量稍作修改。
    2. 系统要保存对象的状态,而对象的状态变换很小。
    3. 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少的几个组合状态,通过复制原型对象得到新实例可能比使用构造函数创建一个新实例更加方便。
    展开全文
  • 设计模式 | 原型模式

    2021-03-14 21:40:15
    类似这种场景在面向对象的软件设计领域被称为原型模式,孙悟空则被成为原型对象。 原型模式的定义 原型模式:使用原型实例指定待创建对象的类型,并通过复制这个原型来创建新的对象。 Prototype Pattern:Spe.
  • 这个模式在 Java、C++ 这种面向对象的语言不太常用,但是如果大家使用过 javascript 的话就会非常熟悉了,因为 js 本身是基于原型的面向对象语言,所以原型模式在 js 中应用非常广泛。 接下来会按照一个类似课程中...
  • 设计模式 - 原型模式 --------目录直通车-------设计模式 - 原型模式一、浅克隆二、深克隆三、克隆破坏单例模式 原型模式是指原型实例指定创建对象的种类,并复制这些原型这些原型创建新的对象。 主要适用于: (1...
  • 设计模式原型模式

    2021-09-07 16:01:01
    原型模式1 原型模式概念1.1 介绍1.2 定义1.3 使用场景2 原型模式UML类图(通用)2. 模式的实现原型模式的应用场景原型模式的扩展 1 原型模式概念 1.1 介绍 原型模式是一个创建型的模式原型二字表明了改模式应该有...
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。例如,一个对象需要在一个高...
  • /*?* WEB开发笔记 ...* 就必须有几个要素:“方法”,“模型”,“工厂车间”。?*//*示例 原型设计模式 原型设计模式也是工厂模式的一种,依赖与clone关键字复制已存在的具体产品。?* */class pepole{}class ...
  • 这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 优点: 1、性能提高。 2、逃避构造函数的约束。 缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于...
  • 什么是原型设计模式 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 说白了原型模式就是通过拷贝的方式创建你要的对象,要拷贝得有个前提就是得先有一个模型。 案例引出(为什么需要...
  • 在有些系统中,存在大量相同或相似对象的创建问题,如果用传统的构造函数来创建对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效,就像孙悟空拔下猴毛轻轻一吹就变出很多孙悟空一样简单。 原型模式的定义...
  • 可以使用 深克隆方式 保存对象的状态,使用原型模式将对象复制一份,并将其状态保存起来,简化了创建对象的过程,以便在需要的时候使用(例如恢复到历史某一状态),可辅助实现撤销操作 原型优势的缺点 需要为每一...
  • 建造者(Builder)模式的定义:指将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。 它是将一个复杂的对象分解为多个简单的对象,然后一步一步构建而成...
  • 原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。
  • 文章目录一 、原型模式的简介1. 什么是原型模式2. 原型模式应用的业务场景二、原型模式的实现1. 原型模式的实现原理2. 原型模式的简单实现2.1 创建一个原型对象2.2 测试原型...原型模式(prototype) 是创建型设计模式
  • 23种设计模式 —— 原型模式【克隆羊、浅拷贝、深拷贝】 文章目录系列文章3、原型模式3.1、传统方式克隆羊3.2、原型模式克隆羊3.3、原型模式在Spring中的源码分析3.4、深拷贝3.5、小结 3、原型模式 3.1、传统方式...
  • 设计模式——原型模式
  • 例如,Windows 中只能打开一个任务管理器,这样可以避免因打开多个任务管理器窗口而造成内存资源的浪费,或出现各个窗口显示内容的不一致等错误。 单例模式有 3 个特点: 单例类只有一个实例对象; 该单例对象必须...
  • C++ 模式设计 原型模式(深拷贝/克隆)

    千次阅读 2021-10-04 16:07:00
    思考: 原型模式跟装饰器模式的区别? 本文核心: WorkExperience* clone(){ WorkExperience *w = new WorkExperience(); *w = *this; // 深拷贝一个相同的自己, 注意如果this中有指针, 需要在对这个指针类进行...
  • 原型模式是一种比较简单的模式,也非常容易理解,实现一个接口,重写一个方法即完成了原型模式。在实际应用中,原型模式很少单独出现。经常与其他模式混用,他的原型类Prototype也常用抽象类来替代。 该模式的思想...
  • 1、 原型模式实现机制原型模式在设计模式中相对比较简单,它直接通过实现 Cloneable接口,再重写 clone()方法返回想要的对象就OK 了。一起来看下代码 :public class ProtoType implements Cloneable {public ...
  • Java常见设计模式总结

    万次阅读 多人点赞 2021-09-18 17:18:54
    设计模式是一套经过反复使用的代码设计经验,目的是为了重用代码、让代码更容易被他人理解、保证代码可靠性。设计模式于己于人于系统都是多赢的,它使得代码编写真正工程化,它是软件工程的基石,如同大厦的一块块...
  • 什么是原型模式 克隆 原型模式是一个创建型的模式原型二字表明了改模式应该有一个样板实例,用户从这个样板对象中复制一个内部属性一致的对象,这个过程也就是我们称的“克隆”。被复制的实例就是我们所称的...
  • 原型模式 概念 Prototype模式是一种对象创建型模式,它采取复制原型对象的方法来创建对象的实例。使用Prototype模式创建的实例,具有与原型一样的数据。 1)由原型对象自身创建目标对象。也就是说,对象创建这一动作...
  • 设计模式 - Prototype 原型模式

    千次阅读 多人点赞 2021-05-17 23:35:46
    前言 在设计模式的系列文章中,我们前面已经写了工厂模式、单列模式、建造者模式,在针对创建型模式中,今天想跟大家分享的是原型模式 其实原型模式在我们的代码中是很常见的,但是又容易被我们所忽视的一种模式,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,344,803
精华内容 937,921
关键字:

原型模式内容