设计模式之 装饰模式&&原型模式

一、装饰模式


1 基础理论
装饰模式:动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更加灵活

装饰模式总结:
为已有功能动态地添加更多功能的一种方式
当系统需要新功能时,是向旧的类中添加新的代码。这些新加的代码通常装饰了原有类的核心职责和主要行为,但这种做法的问题是在主类中加入了新的字段、新的方法、和新的逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定条件下才会执行的特殊行为的需要。
装饰模式提供了一种很好的解决方案,他把每个要装饰的功能放在单独的类中,并让这些类包含它所要装饰的对象,因此当需要执行特殊行为时,客户代码就可以根据在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。
装饰模式的优点:把类中的装饰功能从类中搬移去除,简化原有的类,有效地把类的核心职责和装饰功能区分开了。而且可以去除相关类中重复的装饰逻辑。


2 代码实现

#include<iostream>
using namespace std;
#include<vector>
#include<string>

//父类
class person
{
private:
	string name;
public:
	person() {};
	person(string name) :name(name) {};
	virtual void show()
	{
		cout << "装扮的" << name << endl;
	}
};

//子类一 clothes
class clothes :public person
{
protected:
	person* component;

public:
	void decorate(person* component)
	{
		component = component;
	}
	virtual void show()
	{
		cout << "调用该处:";
		component->show();//通过->调用函数
	}
};

//子类二 jeans
class jeans :public clothes
{
public:
	void show()
	{
		cout << "牛仔";
		component->show();
	}

};

//子类三 T_shits
class T_shits :public clothes
{
public:
	void show()
	{
		cout << "T_shits";
		component->show();
	}
};


int main()
{
	person th("Th");
	jeans* j = new jeans();
	T_shits* t = new T_shits();
	//以下为装饰代码
	j->decorate(&th);
	t->decorate(j);
	t->show();
	return 0;
}

二 原型模式

1 概述
在使用原型模式时,我们需要首先创建一个原型对象,再通过复制这个原型对象来创建更多同类型的对象。

原型模式的定义如下:
原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
原型模式是一种对象创建型模式。

原型模式的工作原理很简单:
将一个原型对象传给那个要发动创建的对象,这个要发动创建的对象通过请求原型对象拷贝自己来实现创建过程。
由于在软件系统中我们经常会遇到需要创建多个相同或者相似对象的情况,因此原型模式在真实开发中的使用频率还是非常高的。
原型模式是一种“另类”的创建型模式,创建克隆对象的工厂就是原型类自身,工厂方法由克隆方法来实现。

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

原型模式的结构如图所示:
在这里插入图片描述
在原型模式结构图中包含如下几个角色:

  ●**Prototype(抽象原型类**):它是声明克隆方法的接口,是所有具体原型类的公共父类,可以是抽象类也可以是接口,甚至还可以是具体实现类。

  ● ConcretePrototype(具体原型类):它实现在抽象原型类中声明的克隆方法,在克隆方法中返回自己的一个克隆对象。

  ● Client(客户类):让一个原型对象克隆自身从而创建一个新的对象,在客户类中只需要直接实例化或通过工厂方法等方式创建一个原型对象,
  再通过调用该对象的克隆方法即可得到多个相同的对象。由于客户类针对抽象原型类Prototype编程,因此用户可以根据需要选择具体原型类,
  系统具有较好的可扩展性,增加或更换具体原型类都很方便

原型模式的核心是如何实现克隆方法


2 代码实现

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

class reuse
{
private:
    string name;
    string sex;
    int age;
    unordered_map<string,string> workExperience;//工作经验
public:
    reuse(string name){
        this->name=name;
    }
    reuse(const reuse &b){//拷贝构造函数
        name=b.name;
        sex=b.sex;
        age=b.age;
        workExperience=b.workExperience;
    }
    reuse& operator=(const reuse & right){//此处重载=运算符
        if(this!=&right){
            name=right.name;
            sex=right.sex;
            age=right.age;
            workExperience=right.workExperience;
        }
        return *this;
    }
    void set_age(int age){
        this->age=age;
    }
    void set_sex(string sex){
        this->sex=sex;
    }
    void set_workExper(string year,string exper){
        workExperience[year]=exper;
    }
    void display(){
        cout<<name<<" "<<sex<<" "<<age<<endl;
        for(auto k:workExperience){
            cout<<k.first<<" "<<k.second<<endl;
        }
    }
};

int main(){
    reuse a("小李");
    a.set_age(20);
    a.set_sex("男");
    a.set_workExper("2018-2019","华为");
    a.display();
    reuse b(a);
    b.display();
    reuse c=b;
    c.display();
    return 0;
}

减少客户端代码中重复对象的生成代码。可以通过在类中实现copy方法。或使用C++的拷贝幅值运算符。拷贝构造函数等技术,实现同类对象的生成。

#include <iostream>
#include <string>
using namespace std;
 
class Resume
{
private:
    string name,sex,age,timeArea,company;
public:
    Resume(string s)
    {
        name=s;
    }
    void setPersonalInfo(string s,string a)
    {
        sex=s;
        age=a;
    }
    void setWorkExperience(string t,string c)
    {
        timeArea=t;
        company=c;
    }
    void display()
    {
        cout<<name<<"  "<<sex<<"  "<<age<<endl;
        cout<<"��������:  "<<timeArea<<"  "<<company<<endl<<endl;

    }
    Resume *clone()
    {
        Resume *b;
        b=new Resume(name);
        b->setPersonalInfo(sex,age);
        b->setWorkExperience(timeArea,company);
        return b;
    }
};


int main()
{
    Resume *r=new Resume("���");    
    r->setPersonalInfo("��","26");
    r->setWorkExperience("2007-2010","�����");
    r->display();
    

    Resume *r2=r->clone();
    r2->setWorkExperience("2003-2007","������");
    
    r->display();
    r2->display();
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.liang呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值