结构型 享元模式共享工厂

简介: 结构型 享元模式共享工厂

享元模式(Flyweight Pattern):用于减少创建对象的数量,以减少内存占用和提高性能。尝试重用现有的同类对象,如果未找到匹配的对象,则创建新对象。 如数据库里的数据池。

享元模式:

重复使用的细粒度的对象的构建和释放,直接一次构造重复使用。

使用场景:

如棋盘游戏,黑白棋子的管理

源码Demo:

参考:C++设计模式——享元模式 - Ring_1992 - 博客园 (cnblogs.com)

/*********************************************************
享元模型: 
  目的是避免大量非常类似的开销。
  如果需要大量相似对象表示数据,只有很少的差异,可以经过一些处理,
把很少差异的参数移动到外部,用传参的方式调用,减少实例化的对象数。
实现demo:
  参考网上实例,如下五子棋,红黑节点的双方一直操作的对象,需要一直操作,可以用一个对象管理。(一个房间管理两个棋手,重复利用对象)
  更加拓展,如棋牌游戏中,如果多个房间,多人下棋,
*********************************************************/
#include <iostream>
#include <map>
#include <vector>
using namespace std;
//管理坐标
typedef struct pointTag
{
    int x;
    int y;
    pointTag(){}
    pointTag(int a, int b)
    {
        x = a;
      y = b;
    }
    bool operator <(const pointTag& other) const
    {
        if (x < other.x)
        {
            return true;
        }
        else if (x == other.x)
        {
            return y < other.y;
        }
        return false;
    }
}POINT;
//管理红黑子
typedef enum PieceColorTag
{
    BLACK,
    WHITE
}PIECECOLOR;
//把棋子的颜色和坐标作为一个对象进行构造
class CPiece
{
public:
    CPiece(PIECECOLOR color) : m_color(color){}
    PIECECOLOR GetColor() { return m_color; }
    void SetPoint(POINT point) { m_point = point; } //拷贝构造
    POINT GetPoint() { return m_point; }
protected:
    PIECECOLOR m_color;
    POINT m_point;
};
//管理棋子
class CGomoku : public CPiece
{
public:
    CGomoku(PIECECOLOR color) : CPiece(color){}
};
//根据黑白棋 定义一个对象 重复使用 ==》根据入参,可以决定不同的选手 
class CPieceFactory
{
public:
    CPiece *GetPiece(PIECECOLOR color)
    {
        CPiece *pPiece = NULL;
      if (m_vecPiece.empty())
      {
      pPiece = new CGomoku(color);
      m_vecPiece.push_back(pPiece);
      }
      else
      {
          for (vector<CPiece *>::iterator it = m_vecPiece.begin(); it != m_vecPiece.end(); ++it)
          {
              if ((*it)->GetColor() == color)
            {
                pPiece = *it;
                break;
            }
          }
          if (pPiece == NULL)
          {
            pPiece = new CGomoku(color);
            m_vecPiece.push_back(pPiece);
          }
      }
        return pPiece;
    }
    ~CPieceFactory()
    {
        for (vector<CPiece *>::iterator it = m_vecPiece.begin(); it != m_vecPiece.end(); ++it)
        {
            if (*it != NULL)
          {
            delete *it;
            *it = NULL;
          }
      }
    }
private:
    vector<CPiece *> m_vecPiece;
};
//棋盘管理
class CChessboard
{
public:
  //落子 节点坐标对应 共享的一个节点对象
    void Draw(CPiece *piece)
    {
      if (piece->GetColor())
      {
          cout<<"Draw a White"<<" at ("<<piece->GetPoint().x<<","<<piece->GetPoint().y<<")"<<endl;
      }
      else
      {
        cout<<"Draw a Black"<<" at ("<<piece->GetPoint().x<<","<<piece->GetPoint().y<<")"<<endl;
      }
      m_mapPieces.insert(pair<POINT, CPiece *>(piece->GetPoint(), piece));
    }
    //显示棋盘上所有的节点
    void ShowAllPieces()
    {
        for (map<POINT, CPiece *>::iterator it = m_mapPieces.begin(); it != m_mapPieces.end(); ++it)
      {
            if (it->second->GetColor())
          {
            cout<<"("<<it->first.x<<","<<it->first.y<<") has a White chese."<<endl;
          }
          else
          {
            cout<<"("<<it->first.x<<","<<it->first.y<<") has a Black chese."<<endl;
          }
      }
    }
private:
    map<POINT, CPiece *> m_mapPieces;
};
int main()
{
  //创建一个棋盘管理房间对象  调用方法根据传参选择对手,重复利用两个对象
    CPieceFactory *pPieceFactory = new CPieceFactory();
    //创建一个棋盘对象 
    CChessboard *pCheseboard = new CChessboard();
  //先手第一个选手 选择白棋 定义坐标并落子
    CPiece *pPiece = pPieceFactory->GetPiece(WHITE); //选定对象
    pPiece->SetPoint(POINT(2, 3));
    pCheseboard->Draw(pPiece);
    //第二个选手  根据颜色找到自己的棋子进行落子
    pPiece = pPieceFactory->GetPiece(BLACK);
    pPiece->SetPoint(POINT(4, 5));
    pCheseboard->Draw(pPiece);
    //第一个选手落子
    pPiece = pPieceFactory->GetPiece(WHITE);
    pPiece->SetPoint(POINT(2, 4));
    pCheseboard->Draw(pPiece);
    //第二个选手落子
    pPiece = pPieceFactory->GetPiece(BLACK);
    pPiece->SetPoint(POINT(3, 5));
    pCheseboard->Draw(pPiece);
    //展示棋盘上所有的落子
    cout<<"Show all cheses"<<endl;
    pCheseboard->ShowAllPieces();
    //删除棋盘
    if (pCheseboard != NULL)
    {
      delete pCheseboard;
      pCheseboard = NULL;
    }
    //删除房间
    if (pPieceFactory != NULL)
    {
      delete pPieceFactory;
      pPieceFactory = NULL;
    }
    return 0;
}
目录
相关文章
|
Java
SpringBoot中的拦截器 interceptor
SpringBoot中的拦截器 interceptor
139 0
|
Web App开发 前端开发 JavaScript
React 之 requestAnimationFrame 执行机制探索
React 之 requestAnimationFrame 执行机制探索
456 0
|
7月前
|
网络协议 Linux 网络安全
微软工程师偷偷在用!这款SSH工具让Windows操控CentOS比Mac还优雅!
远程登录Linux服务器是管理和维护服务器的重要手段,尤其在远程办公、云服务管理等场景中不可或缺。通过工具如XShell,用户可以方便地进行远程管理。SSH协议确保了数据传输的安全性,命令行界面提高了操作效率。配置XShell连接CentOS时,需确保Linux系统开启sshd服务和22端口,并正确设置主机地址、用户名和密码。此外,调整字体和配色方案可优化使用体验,解决中文显示问题。
320 21
微软工程师偷偷在用!这款SSH工具让Windows操控CentOS比Mac还优雅!
|
12月前
|
人工智能 算法 JavaScript
无界 SaaS AI 生态大模型:技术在中国,链接全世界
无界 SaaS AI 生态大模型涵盖前端用户界面、后端服务器逻辑、数据库设计、API 接口开发及区块链技术应用。本文提供一个简化框架,介绍技术栈选择、核心功能模块(用户管理、商城、数据确权、链接力、算力算法、AI 生态大模型、全球化支持)及后端示例代码,帮助将商业模式转化为代码。
|
9月前
|
存储 架构师 容灾
阿里云基础设施高可用最佳实践沙龙上海站圆满举办!
2025年1月9日,阿里云在上海虹桥绿地铂瑞酒店成功举办基础设施高可用最佳实践沙龙NO.2。活动吸引了华东地区多家企业的CTO、架构师和技术从业者参与。专家们分享了高可用的基础知识、分级标准及云端架构实战经验,涵盖计算、存储、网络和云原生等领域,重点讨论了企业如何在阿里云上构建高可用数据中心。现场互动热烈,参会者与专家深入交流,探讨技术应用与合作机会。
|
机器学习/深度学习 人工智能 数据可视化
【2024美国大学生数学建模竞赛】2024美赛C题网球运动中的势头,网球教练4.0没人比我更懂这个题了!!!
本文是一位自称对网球规则和比赛数据非常熟悉的计算机博士对2024美国大学生数学建模竞赛C题"网球运动中的势头"的全面解析,包括问题分析、数学模型构建、代码实现,以及完整论文的逐步更新过程。
251 1
【2024美国大学生数学建模竞赛】2024美赛C题网球运动中的势头,网球教练4.0没人比我更懂这个题了!!!
|
消息中间件 运维 Java
RocketMQ的常规运维实践应用
RocketMQ的常规运维实践应用
|
存储 分布式计算 大数据
现代化数据库技术——面向大数据的分布式存储系统
传统的关系型数据库在面对大规模数据处理时遇到了诸多挑战,而面向大数据的分布式存储系统应运而生。本文将深入探讨现代化数据库技术中的分布式存储系统,包括其优势、工作原理以及在大数据领域的应用。
|
机器学习/深度学习 编解码 算法
R语言用FNN-LSTM假近邻长短期记忆人工神经网络模型进行时间序列深度学习预测4个案例
R语言用FNN-LSTM假近邻长短期记忆人工神经网络模型进行时间序列深度学习预测4个案例