设计模式学习–原型模式

设计模式学习–原型模式

文章理论部分参考以下链接

http://www.runoob.com/design-pattern/prototype-pattern.html

一、原型模式介绍

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

意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
主要解决:在运行期建立和删除原型。
何时使用: 1、当一个系统应该独立于它的产品创建,构成和表示时。 2、当要实例化的类是在运行时刻指定时,例如,通过动态装载。 3、为了避免创建一个与产品类层次平行的工厂类层次时。 4、当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
如何解决:利用已有的一个原型对象,快速地生成和原型对象一样的实例。
关键代码: 1、实现克隆操作,在 JAVA 继承 Cloneable,重写 clone(),在 .NET 中可以使用 Object 类的 MemberwiseClone() 方法来实现对象的浅拷贝或通过序列化的方式来实现深拷贝。 2、原型模式同样用于隔离类对象的使用者和具体类型(易变类)之间的耦合关系,它同样要求这些”易变类”拥有稳定的接口。
应用实例: 1、细胞分裂。 2、JAVA 中的 Object clone() 方法。
优点: 1、性能提高。 2、逃避构造函数的约束。
缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、逃避构造函数的约束。
使用场景:
1、资源优化场景。
2、类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
3、性能和安全要求的场景。
4、通过 new 产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
5、一个对象多个修改者的场景。
6、一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。
7、在实际项目中,原型模式很少单独出现,一般是和工厂方法模式一起出现,通过 clone 的方法创建一个对象,然后由工厂方法提供给调用者。
注意事项:与通过对一个类进行实例化来构造新对象不同的是,原型模式是通过拷贝一个现有对象生成新对象的。浅拷贝实现 Cloneable,重写,深拷贝是通过实现 Serializable 读取二进制流。

UML结构图
抽象基类:
l)Prototype:虚拟基类,所有原型的基类,提供Clone接口函数
接口函数:
1) Prototype::Clone函数:纯虚函数,根据不同的派生类来实例化创建对象.
解析:
原型模式其实就是常说的”虚拟构造函数”一个实现,C++的实现机制中并没有支持这个特性,但是通过不同派生类实现的Clone接口函数可以完成与”虚拟构造函数”同样的效果。举一个例子来解释这个模式的作用,假设有一家店铺是配钥匙的,他对外提供配制钥匙的服务(提供Clone接口函数),你需要配什么钥匙它不知道只是提供这种服务,具体需要配什么钥匙只有到了真正看到钥匙的原型才能配好.也就是说,需要一个提供这个服务的对象,同时还需要一个原型(Prototype),不然不知道该配什么样的钥匙.

二、实现演练

首先,给出对UML结构图对应的解释代码。

//虚拟基类,所有原型的基类,提供Clone接口函数
class Prototype
{
public:
    Prototype(){}
    virtual ~Prototype(){}
    virtual Prototype* Clone()=0;
};
//派生自Prototype,实现Clone方法
class ConcretePrototype1:public Prototype
{
public:
    ConcretePrototype1()
    { 
        cout<<"ConcretePrototype1"<<endl;
    }
    ConcretePrototype1(const ConcretePrototype1& p)
    { 
        cout<<"ConcretePrototype1 copy..."<<endl; 
    }
    virtual ~ConcretePrototype1(){}
    virtual Prototype* Clone()
    { 
        return new ConcretePrototype1(*this); 
    }
};
//派生自Prototype,实现Clone方法
class ConcretePrototype2:public Prototype
{
public:
    ConcretePrototype2()
    { 
        cout<<"ConcretePrototype2"<<endl;
    }
    ConcretePrototype2(const ConcretePrototype2& p)
    { 
        cout<<"ConcretePrototype2 copy..."<<endl; 
    }
    virtual ~ConcretePrototype2(){}
    virtual Prototype* Clone()
    { 
        return new ConcretePrototype2(*this); 
    }
};

int main()
{
    Prototype* p1 = new ConcretePrototype1();
    Prototype* p2 = p1->Clone();
    Prototype* p3 = new ConcretePrototype2();
    Prototype* p4 = p3->Clone();
    delete p1;
    delete p2;
    delete p3;
    delete p4;
    return 0;
}

再来,给出一个网上看到的例子。
(1)创建一个虚拟基类,所有原型的基类,提供Clone接口函数。

// 克隆接口  
template<class T>  
class ICloneable  
{  
public:  
    virtual T* clone() = 0;  
};  

(2)创建一个工作经历类,它用来丰富原型类的内容。

class CWorkExperience  
{  
public:  
    CWorkExperience(){}  

    CWorkExperience(const string& company,  
        const string& workTime)  
    {  
        m_strCompany = company;  
        m_strWorkTime = workTime;  
    }  

    CWorkExperience(const CWorkExperience& right)  
    {  
        m_strCompany = right.m_strCompany;  
        m_strWorkTime = right.m_strWorkTime;  
    }  

    ~CWorkExperience()  
    {  
        cout << "CWorkExperience析构" << endl;  
        printInfo();  
    }  

    void setCompany(const string& company)  
    {  
        m_strCompany = company;  
    }  

    const string& getCompany() const  
    {  
        return m_strCompany;  
    }  

    void setWorkTime(const string& workTime)  
    {  
        m_strWorkTime = workTime;  
    }  

    const string& getWorkTime() const  
    {  
        return m_strWorkTime;  
    }  

    void printInfo()  
    {  
        cout << "Company: " << m_strCompany << endl;  
        cout << "WorkTime: " << m_strWorkTime << endl;  
    }  

private:  
    string m_strCompany;        // company name  
    string m_strWorkTime;       // work time  
};  

(3)派生自Prototype基类,实现Clone方法

// 简历类  
class CResume : public ICloneable<CResume>  
{  
public:  
    CResume(){}  
    ~CResume()  
    {  
        cout << "CResume析构 " << m_name << endl;  
    }  

    void setInfo(const string& name, const string& sex  
        , int age)  
    {  
        m_name = name;  
        m_sex = sex;  
        m_age = age;  
    }  

    void setExperience(const string& company, const string& workTime)  
    {  
        m_experience.setCompany(company);  
        m_experience.setWorkTime(workTime);  
    }  

    CResume* clone()  
    {  
        CResume* resume = new CResume;  
        resume->setInfo(m_name, m_sex, m_age);  
        resume->setExperience(m_experience.getCompany(), m_experience.getWorkTime());  
        return resume;  
    } 
    /*浅拷贝的实现 
    CResume(const CResume& right)  
    {  
        m_name = right.m_name;  
        m_sex = right.m_sex;  
        m_age = right.m_age;  
        // 注意这里是指针赋值 属于浅拷贝  
        m_experience = right.m_experience;  
    }  */ 

    void printInfo()  
    {  
        cout << "Name: " << m_name << endl;  
        cout << "Sex: " << m_sex << endl;  
        cout << "Age: " << m_age << endl;  
        cout << "Experience: " << endl;  
        m_experience.printInfo();  
        cout << endl;  
    }  
protected:  
    string m_name;  
    string m_sex;  
    int m_age;  

    CWorkExperience m_experience;// 对象  
};  

(4)测试功能的函数

void testPrototype()  
{  
    CResume re;  
    re.setInfo("Jacky", "Male", 20);  
    re.setExperience("MS", "2001.11 - 2005.11");  
    re.printInfo();  

    CResume* pClone = re.clone();  
    pClone->setInfo("Marry", "Female", 30);  
    pClone->setExperience("Google", "2006.01 - 2010.01");  
    pClone->printInfo();  

    delete pClone;  
    pClone = NULL;  
}  

int main(void)  
{  
    testPrototype();  

    return 0;  
}  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于微信小程序的家政服务预约系统采用PHP语言和微信小程序技术,数据库采用Mysql,运行软件为微信开发者工具。本系统实现了管理员和客户、员工三个角色的功能。管理员的功能为客户管理、员工管理、家政服务管理、服务预约管理、员工风采管理、客户需求管理、接单管理等。客户的功能为查看家政服务进行预约和发布自己的需求以及管理预约信息和接单信息等。员工可以查看预约信息和进行接单。本系统实现了网上预约家政服务的流程化管理,可以帮助工作人员的管理工作和帮助客户查询家政服务的相关信息,改变了客户找家政服务的方式,提高了预约家政服务的效率。 本系统是针对网上预约家政服务开发的工作管理系统,包括到所有的工作内容。可以使网上预约家政服务的工作合理化和流程化。本系统包括手机端设计和电脑端设计,有界面和数据库。本系统的使用角色分为管理员和客户、员工三个身份。管理员可以管理系统里的所有信息。员工可以发布服务信息和查询客户的需求进行接单。客户可以发布需求和预约家政服务以及管理预约信息、接单信息。 本功能可以实现家政服务信息的查询和删除,管理员添加家政服务信息功能填写正确的信息就可以实现家政服务信息的添加,点击家政服务信息管理功能可以看到基于微信小程序的家政服务预约系统里所有家政服务的信息,在添加家政服务信息的界面里需要填写标题信息,当信息填写不正确就会造成家政服务信息添加失败。员工风采信息可以使客户更好的了解员工。员工风采信息管理的流程为,管理员点击员工风采信息管理功能,查看员工风采信息,点击员工风采信息添加功能,输入员工风采信息然后点击提交按钮就可以完成员工风采信息的添加。客户需求信息关系着客户的家政服务预约,管理员可以查询和修改客户需求信息,还可以查看客户需求的添加时间。接单信息属于本系统里的核心数据,管理员可以对接单的信息进行查询。本功能设计的目的可以使家政服务进行及时的安排。管理员可以查询员工信息,可以进行修改删除。 客户可以查看自己的预约和修改自己的资料并发布需求以及管理接单信息等。 在首页里可以看到管理员添加和管理的信息,客户可以在首页里进行家政服务的预约和公司介绍信息的了解。 员工可以查询客户需求进行接单以及管理家政服务信息和留言信息、收藏信息等。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值