C++设计模式---享元模式

什么是享元模式

享元模式是一种结构型设计模式, 它摒弃了在每个对象中保存所有数据的方式, 通过共享多个对象所共有的相同状态, 让你能在有限的内存容量中载入更多对象。

为什么使用享元模式

通过复用相同的对象来减少对象的创建数量,创建更小的对象组,并通过共享实现重用。通过归类,将对象的属性分为内蕴状态和外蕴状态。

外蕴状态是对象的外部描述,是每个对象的可变部分,比如对工具的使用地点、使用时间、使用人、工作内容的描述,这些属性不属于对象本身,而是根据每回使用情况进行变化的,这就需要制作成接口进行外部调用,而外蕴状态的维护是由调用者维护的,对象内不进行维护。

享元模式实现步骤

1.提供一个抽象享元角色类:具体享元类的父类,规定一些需要实现的公共接口

2.提供一个或者多个具体享元角色:实现了抽象享元角色规定的方法

3.提供一个享元工厂角色类:负责创建和管理享元角色
在这里插入图片描述

享元模式实现代码

//车库信息
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#include <initializer_list>
using namespace std;
//事物属性抽象,分为两部分
class SharedState 
{
public:
    SharedState(const string brand, const string model, const string color) :
        brand(brand), model(model), color(color) {}
    const string GetBrand() const { return brand; }
    const string GetModel()const { return model; }
    const string GetColor()const { return color; }
    friend ostream& operator<<(ostream& out, const SharedState ss) 
    {
        return out << "[" << ss.brand << "," << ss.model << "," << ss.color << "]";
    }
private:
    string brand;       //品牌
    string model;       //型号
    string color;       //颜色
};
class UniqueState
{
public:
    UniqueState(const string owner, const string plates) :owner(owner), plates(plates) {}
    const string GetOwner()const { return owner; }
    const string GetPlates() const { return plates; }
    friend ostream& operator<<(ostream& out, const UniqueState ss) 
    {
        return out << "[" << ss.owner << "," << ss.plates << "]";
    }
private:
    string owner;       //车主
    string plates;      //车牌号
};
class Flyweight 
{
private:
    SharedState* sharedstate;
public:
    Flyweight(const SharedState* sharedstate) :sharedstate(new SharedState(*sharedstate)) 
    {
    }
    Flyweight(const Flyweight& other) :sharedstate(new SharedState(*other.sharedstate)) 
    {
​
    }
    SharedState* GetSharedState()const { return sharedstate; }
    void Show(const UniqueState& uniquestate)const 
    {
        cout << "共享数据:" << *sharedstate << endl;
        cout << "专有数据:" << uniquestate << endl;
    }
};
​
class FlyweightFactory 
{
private:
    map<string, Flyweight> flyweight;
    string GetKey(const SharedState& ss) const 
    {
        return  ss.GetBrand() + '_' + ss.GetModel() + "_" + ss.GetColor();
    }
​
public:
    FlyweightFactory(initializer_list<SharedState> sharedstate) 
    {
        for (auto v : sharedstate) 
        {
            this->flyweight.insert(make_pair<string, Flyweight>(this->GetKey(v), Flyweight(&v)));
        }
    }
    Flyweight  GetFlyweight(const SharedState& sharedstate)
    {
        string key = this->GetKey(sharedstate);
        if (this->flyweight.find(key) == this->flyweight.end())
        {
            cout << "车库未找到这个款式......" << endl;
            this->flyweight.insert(make_pair(key, Flyweight(&sharedstate)));
            cout << "第一次入库成功" << endl;
        }
        else 
        {
            cout << "车库找到这个款式......" << endl;
        }
        return this->flyweight.at(key);
    }
    void ListFlyweights() const 
    {
        int count = this->flyweight.size();
        cout << "车库总信息:" << endl;
        for (auto pair : this->flyweight) 
        {
            cout << pair.first << "\n";
        }
    }
};
​
void AddCar(FlyweightFactory& ff, const string& plates, const string& owner, const string& brand, const string& model, const string& color)
{
    cout << "车型匹配结果:" << endl;
    auto flyweight = ff.GetFlyweight({ brand,model,color });
    flyweight.Show({ owner,plates });
}
​
int main() 
{
    FlyweightFactory* f = new FlyweightFactory(
        {
            {"雪佛兰","Camaro2020","pink"},
            {"奔驰","C43","black"},
            {"奔驰","C63","red"},
            {"宝马","M6","red"},
            {"宝马","X7","white"},
        });
    f->ListFlyweights();
    cout << endl << endl;
    AddCar(*f, "DK88888", "顽石", "宝马", "M6", "red");
    AddCar(*f, "DK66666", "里奇", "宝马", "X7", "red");
    f->ListFlyweights();
    delete f;
    return 0;
}

享元模式优缺点

优点
如果程序中有很多相似对象, 那么你将可以节省大量内存。

缺点
你可能需要牺牲执行速度来换取内存, 因为他人每次调用享元方法时都需要重新计算部分情景数据。
代码会变得更加复杂。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值