C++享元模式(10)

享元模式

什么是享元模式

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

为什么使用享元模式

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

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

享元模式实现步骤

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

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

3.提供一个享元工厂角色类:负责创建和管理享元角色

//车库信息
#include <initializer_list>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
using namespace std;
class SharedState {
   public:
    SharedState(const string brand, const string model, const string color)
        : brand(brand), model(model), color(color) {}
    friend ostream& operator<<(ostream& out, const SharedState ss) {
        out << "[" << ss.brand << "," << ss.model << "," << ss.color << "]";
        return out;
    }
    const string& GetBrand() const { return brand; }
    const string& GetModel() const { return model; }
    const string& GetColor() const { return color; }

   private:
    string brand;  //品牌
    string model;  //型号
    string color;  //颜色
};
class UniqueState {
   public:
    UniqueState(const string owner, const string plates)
        : owner(owner), plates(plates) {}
    friend ostream& operator<<(ostream& out, const UniqueState ss) {
        return out << "[" << ss.owner << "," << ss.plates << "]";
    }
    const string& GetOwer() const { return owner; }
    const string& GetPlates() const { return plates; }

   private:
    string owner;   //车主
    string plates;  //车牌
};
class Flyweight {
   private:
    SharedState* shared_state;

   public:
    Flyweight(const SharedState* shared_state)
        : shared_state(new SharedState(*shared_state)) {}
    Flyweight(const Flyweight& other)
        : shared_state(new SharedState(*other.shared_state)) {}
    SharedState* Get_shared_state() const { return shared_state; }
    void Operation(const UniqueState& unique_state) const {
        cout << "shared:" << *shared_state << endl
             << "unique:" << unique_state << endl;
    }
};
class FlayweightFactory {
   private:
    map<string, Flyweight> flyweight;
    string GetKey(const SharedState& ss) const {
        return ss.GetBrand() + "_" + ss.GetModel() + "_" + ss.GetColor();
    }

   public:
    FlayweightFactory(initializer_list<SharedState> shared_state) {
        for (const SharedState& ss : shared_state) {
            this->flyweight.insert(
                make_pair<string, Flyweight>(this->GetKey(ss), Flyweight(&ss)));
        }
    }
    Flyweight GetFlweight(const SharedState& shared_state) {
        string key = this->GetKey(shared_state);
        if (this->flyweight.find(key) == this->flyweight.end()) {
            cout << "车库未找到....." << endl;
            this->flyweight.insert(make_pair(key, Flyweight(&shared_state)));
            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 AddCarToPoliceDataBase(FlayweightFactory& ff,
                            const string& plates,
                            const string& ower,
                            const string& brand,
                            const string& model,
                            const string& color) {
    cout << "车型匹配结果:" << endl;
    const Flyweight& flyweight = ff.GetFlweight({brand, model, color});
    flyweight.Operation({ower, plates});
}
int main() {
    FlayweightFactory* factory =
        new FlayweightFactory({{"雪佛兰", "Camaro2020", "pink"},
                               {"奔驰", "C43", "black"},
                               {"奔驰", "C63", "red"},
                               {"宝马", "M6", "red"},
                               {"宝马", "X7", "white"}});
    AddCarToPoliceDataBase(*factory, "DK88888", "麦克", "宝马", "M6", "red");
    AddCarToPoliceDataBase(*factory, "DK66666", "肖邦", "宝马", "X7", "red");
    factory->ListFlyweights();
    delete factory;
    return 0;
}

享元模式优缺点

优点

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

缺点

  • 你可能需要牺牲执行速度来换取内存, 因为他人每次调用享元方法时都需要重新计算部分情景数据。

  • 代码会变得更加复杂。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值