商城网站的psd模板免费下载,电商网站建设需要哪些技术,如何给一个公司做网站,公司主页网站怎么做什么是享元模式#xff1f;
享元模式是一个非常实用的结构型设计模式#xff0c;它的主要目的是节省内存#xff0c;尤其在需要创建大量相似对象时。
通俗解释#xff1a; 想象我们在写一本书#xff0c;每个字母都需要表示出来。如果每个字母都单独用对象表示#xff…什么是享元模式
享元模式是一个非常实用的结构型设计模式它的主要目的是节省内存尤其在需要创建大量相似对象时。
通俗解释 想象我们在写一本书每个字母都需要表示出来。如果每个字母都单独用对象表示不仅创建对象的成本高而且内存占用也很大。但是字母其实是有限的比如英文字母只有26个大小写字母我们可以让所有相同的字母对象共享只存储不同的额外信息比如字母的字体、颜色等。
通过这种方式我们避免了重复创建相同的字母对象从而节省了大量内存。这就是享元模式的核心思想将可以共享的部分抽取出来共享用少量对象完成大量对象的表示。 享元模式的原理
享元模式的核心在于分离对象的状态 内在状态Intrinsic State 对象中可以共享、不变的部分。例如字母的实际内容‘A’、B’等就是内在状态。 外在状态Extrinsic State 对象中不可以共享、经常变化的部分。例如字母的字体、颜色、大小等就是外在状态由客户端传递。
通过将状态分离享元模式可以将内在状态共享避免重复创建对象进而节省内存。 享元模式的组成
享元模式通常包含以下几个角色
Flyweight享元接口定义享元对象的公共接口。ConcreteFlyweight具体享元类实现享元接口表示可以共享的具体对象。UnsharedConcreteFlyweight非共享享元类可选表示不需要共享的享元类。FlyweightFactory享元工厂管理享元对象的创建和共享确保相同的享元对象只会被创建一次。Client客户端使用享元对象将外在状态传递给享元对象。 案例文字处理系统中的字符对象
场景描述
我们需要实现一个简单的文字处理系统其中
每个字符用一个对象表示。字符内容‘A’、B’等是固定的可以共享内在状态。字符的字体、大小、颜色等信息是外在状态由客户端动态传递。
实现目标
利用享元模式共享相同的字符对象避免重复创建。通过外在状态动态调整字符的显示样式。 代码实现
以下是完整的代码实现输出信息为中文并配有详细的注释。
#include iostream
#include unordered_map
#include string
#include memory// 抽象享元类Flyweight
class Flyweight {
public:// 展示字符信息结合外在状态进行操作virtual void display(const std::string 字体, int 大小, const std::string 颜色) const 0;virtual ~Flyweight() default;
};// 具体享元类ConcreteFlyweight
class ConcreteFlyweight : public Flyweight {
private:char 内在状态; // 内在状态表示字符内容public:explicit ConcreteFlyweight(char c) : 内在状态(c) {}// 实现展示方法void display(const std::string 字体, int 大小, const std::string 颜色) const override {std::cout 字符: 内在状态 , 字体: 字体 , 大小: 大小 , 颜色: 颜色 std::endl;}
};// 享元工厂类FlyweightFactory
class FlyweightFactory {
private:std::unordered_mapchar, std::shared_ptrFlyweight flyweights; // 存储享元对象public:// 获取享元对象std::shared_ptrFlyweight getFlyweight(char c) {// 如果享元对象不存在则创建一个新的对象if (flyweights.find(c) flyweights.end()) {flyweights[c] std::make_sharedConcreteFlyweight(c);std::cout 创建新的享元对象: c std::endl;}return flyweights[c];}// 获取享元对象的总数size_t getFlyweightCount() const {return flyweights.size();}
};// 客户端代码
int main() {FlyweightFactory 工厂; // 创建享元工厂// 获取并使用享元对象auto 字符A 工厂.getFlyweight(A);auto 字符B 工厂.getFlyweight(B);auto 字符C 工厂.getFlyweight(C);// 重复获取相同的享元对象auto 字符A2 工厂.getFlyweight(A);// 使用享元对象传递外在状态字符A-display(微软雅黑, 12, 红色);字符B-display(宋体, 14, 蓝色);字符C-display(楷体, 10, 绿色);字符A2-display(黑体, 16, 黑色);// 输出享元对象的总数std::cout 享元对象的总数: 工厂.getFlyweightCount() 个 std::endl;return 0;
}运行结果
运行上述代码后输出结果如下
创建新的享元对象: A
创建新的享元对象: B
创建新的享元对象: C
字符: A, 字体: 微软雅黑, 大小: 12, 颜色: 红色
字符: B, 字体: 宋体, 大小: 14, 颜色: 蓝色
字符: C, 字体: 楷体, 大小: 10, 颜色: 绿色
字符: A, 字体: 黑体, 大小: 16, 颜色: 黑色
享元对象的总数: 3 个代码讲解
1. 抽象享元类
class Flyweight {
public:virtual void display(const std::string 字体, int 大小, const std::string 颜色) const 0;virtual ~Flyweight() default;
};定义了一个抽象接口display表示字符的展示方法。外在状态字体、大小、颜色由客户端传递。 2. 具体享元类
class ConcreteFlyweight : public Flyweight {
private:char 内在状态; // 内在状态public:explicit ConcreteFlyweight(char c) : 内在状态(c) {}void display(const std::string 字体, int 大小, const std::string 颜色) const override {std::cout 字符: 内在状态 , 字体: 字体 , 大小: 大小 , 颜色: 颜色 std::endl;}
};内在状态字符内容在对象创建时确定表示可共享的部分。display方法结合外在状态动态显示字符信息。 3. 享元工厂类
class FlyweightFactory {
private:std::unordered_mapchar, std::shared_ptrFlyweight flyweights;public:std::shared_ptrFlyweight getFlyweight(char c) {if (flyweights.find(c) flyweights.end()) {flyweights[c] std::make_sharedConcreteFlyweight(c);std::cout 创建新的享元对象: c std::endl;}return flyweights[c];}size_t getFlyweightCount() const {return flyweights.size();}
};工厂管理共享对象的创建与缓存。如果享元对象不存在则创建如果已经存在则直接返回。 4. 客户端代码
字符A-display(微软雅黑, 12, 红色);
字符B-display(宋体, 14, 蓝色);
字符C-display(楷体, 10, 绿色);
字符A2-display(黑体, 16, 黑色);客户端从工厂获取享元对象并传递外在状态来控制字符的显示。字符A和A2实际上是同一个对象只是使用了不同的外在状态。 享元模式的优缺点
优点
内存节省通过共享对象避免了重复创建相似对象大幅降低内存开销。性能提升减少了对象的创建和销毁提升系统性能。统一管理通过工厂集中管理共享对象便于维护。
缺点
复杂性增加需要区分内在状态和外在状态设计复杂度增加。适用场景有限只有当对象中有可共享部分时享元模式才适用。 适用场景
文字处理系统字母、数字等字符对象共享。图形系统共享重复出现的形状或纹理。游戏开发共享重复出现的敌人、道具等。 总结
享元模式通过共享内在状态有效减少了内存开销和对象创建的成本是一种针对性能优化的设计模式。在需要处理大量重复对象的场景中享元模式是一个非常实用的解决方案。
本文由mdnice多平台发布