如何在模块中共享数据

在与业务逻辑相关的模块中,不同的类之间共享一些数据是再平常不过的事啦。在前两年的程序员生涯中,我主要采用过两种方式:

使用数据管理类

我所在公司的应用程序框架使用的是MVC三层架构,由于历史原因,每个模板都由一个Model,一个controller加上一系列的View组成,所有要共享的数据都存在Model中,Model提供setter和访问接口:

SetObject(int nObjectID,Object*pObject);

Object*GetObject(int nObjectID);

这样,如果你要共享一个自定义的对象,拿AddressBook来说吧你需要做如下事情:

1) 从Object继承下来;

class AddressBook:public Object

{…};

2) 调用setter方法存储数据:

m_pModel->SetObject(ID_ADDRESS_BOOK,newAddressBook);

3) 使用共享数据:

AddressBook * pObject = (AddressBook *)m_pModel->GetObject(ID_ADDRESS_BOOK);

这个方法的优点:

1) 简单;

2) 数据封闭在同一模块,在其他模块访问到本模块数据的可能性不大。

缺点如下:

1) 在Model,View,Controller之外模块其他部分很难得到这些共享数据,而它们本来应该是对整个模块可见的。要在其他部分得到这些共享数据,必须得将model设置进去;

2) 如果要多线程访问,就会比较地麻烦;

3) 不是类型安全的。

使用Singleton模式

我也曾经思考过将共享数据用一个单例来管理,但是好像从逻辑上来说,这些数据不是整个应用程序所有,而是一个模块所有,而且基本上也只能弥补第一种方法的第一个缺陷。代价是整个应用程序中到处充斥着这种单例。所以我不认为这种方法可取。

由于没有找到什么好的方法,所以我当时决定还是用第一种方案,不过内心总有个疙瘩。 直到前几天,我发现了一个更好的方法,拿出来共享一下.

用对象标识+引用计数方案

首先看一下在这种方案下如何共享数据是有益处的:

1) 申明要共享的对像:

SharedDataHolder m_strAddress(“Address book”,aAddrBook);

2) 使用共享对象:

ShareDataHolderaAddressBook(“Address book”);

aAddressBook->somemethod();

很简单吧。使用和申明是可以分开的,你可以在不引入任何依赖的情况下使用这些数据!!!而且申明和使用大同小异。

好了,现在可以看一下是如何实现的。

每一个共享数据都有一个id,用什么都行,只要能唯一地标识一个对象就成,对象在第一次出现时,会将自己注册到一个std::map中。以后在要使用这个数据只是增加引用计数而已。

在下面这个示例的实现中主要包含两个类:

1)StorePolicy. 这是个类模板Policy(如果你对这种技巧不是十分地熟,你可真要仔细研究一下《C++ Template》这本书啦),其用途是定义各种类型的存储格式:内置类型,真接存值,自定义类型,存指针。同时它还得提供类型的默认值和消毁方法。

2)SharedDataHolder:应用程序主要应该和它打交道,它有一个类静态变量g_oSharedDatabase用来保存共享的数据,保存在其中的对象都是引用计数的,在引用计数为0时被销毁。你可以通过3种方法来申明一个共享对象,因为它定义了3个构造函数(你也可以加上赋值函数等等)。

对于基本数据类型,可以调用它的 value方法得到其值。

对于自定义类型,你可以像指针一样使用对象

源代码如下:

如何在模块中共享数据如何在模块中共享数据代码

#ifndef _SHAREDSTOREPOLICY_H#define _SHAREDSTOREPOLICY_Htemplate<typename T>struct StorePolicy{    typedef T*    StoreType;    static StoreType getDefaultValue()    {        return new T();    }    static StoreType getDefaultValue(const T& rCopy)    {        return new T(rCopy);    }    static void    destroyValue(StoreType pData)    {        delete pData;    }    static T&  getValue(StoreType pData)    {        return *pData;    }};#define MAKE_FUNADTION_STORE_POLICY(type)                      template<>                                                  struct StorePolicy<type>                                  {                                                              typedef type    StoreType;                                  static StoreType getDefaultValue()                          {                                                              return StoreType();                                      }                                                          static StoreType getDefaultValue(StoreType rCopy)         {                                                              return StoreType(rCopy);                              }                                                          static void    destroyValue(StoreType pData)                  {                                                          }                                                          static type&  getValue(StoreType& pData)                  {                                                              return pData;                                          }                                                      }; MAKE_FUNADTION_STORE_POLICY(bool)MAKE_FUNADTION_STORE_POLICY(char)MAKE_FUNADTION_STORE_POLICY(signed char)MAKE_FUNADTION_STORE_POLICY(unsigned char)MAKE_FUNADTION_STORE_POLICY(wchar_t)MAKE_FUNADTION_STORE_POLICY(signed short)MAKE_FUNADTION_STORE_POLICY(unsigned short)MAKE_FUNADTION_STORE_POLICY(signed int)MAKE_FUNADTION_STORE_POLICY(unsigned int)MAKE_FUNADTION_STORE_POLICY(signed long)MAKE_FUNADTION_STORE_POLICY(unsigned long)#if LONGLONG_EXISTSMAKE_FUNADTION_STORE_POLICY(signed long long)MAKE_FUNADTION_STORE_POLICY(unsigned long long)#endif //LONGLONG_EXISTSMAKE_FUNADTION_STORE_POLICY(float)MAKE_FUNADTION_STORE_POLICY(double)MAKE_FUNADTION_STORE_POLICY(long double)#undef MAKE_FUNADTION_STORE_POLICY#endif

如何在模块中共享数据如何在模块中共享数据代码

#ifndef _SHAREDDATAHOLDER_HPP#define _SHAREDDATAHOLDER_HPP#include <string>#include <map>#include <utility>#include "SharedStorePolicy.h"template<typename T>class SharedDataHolder{public:    typedef typename StorePolicy<T>::StoreType StoreDataType;                  typedef std::pair<int,StoreDataType> DatabaseItemType;                              SharedDataHolder(const std::string& strKey):                                        m_strKey(strKey)                                                                    ,m_rData(g_oSharedDatabase[strKey])                                                 {             if (0 == g_oSharedDatabase[m_strKey].first)                                            {                                                                                       g_oSharedDatabase[m_strKey].second = StorePolicy<T>::getDefaultValue();          }                                                                                   ++m_rData.first;                                                                }                                                                                   SharedDataHolder(const std::string& strKey,const T& rData):                            m_strKey(strKey)                                                                    ,m_rData(g_oSharedDatabase[strKey])                                                 {                                                                                       if (0 == g_oSharedDatabase[strKey].first)                                            {                                                                                       g_oSharedDatabase[m_strKey].second = StorePolicy<T>::getDefaultValue(rData);          }                                                                                   ++m_rData.first;                                                                }                                                                                   SharedDataHolder(const SharedDataHolder& rhs):                                      m_strKey(rhs.m_strKey)                                                              ,m_rData(rhs.m_rData)                                                               {                                                                                       ++m_rData.first;                                                                }                                                                                   ~SharedDataHolder( void )                                                           {                                                                                       if (0 == --m_rData.first)                                                           {                                                                                   StorePolicy<T>::destroyValue(m_rData.second);                                       g_oSharedDatabase.erase(g_oSharedDatabase.find(m_strKey));                      }                                                                               }                                                                                   public:    StoreDataType operator->( void )    {        return m_rData.second;    }    const StoreDataType operator->( void )const    {        return m_rData.second;    }    T& operator*( void )    {        return StorePolicy<T>::getValue(m_rData.second);    }    const T& operator*( void )const    {        return StorePolicy<T>::getValue(m_rData.second);    }    T& value( void ) {return StorePolicy<T>::getValue(m_rData.second);}                                const T& value( void )const {return StorePolicy<T>::getValue(m_rData.second);}        private:                                                                        std::string    m_strKey;                                                        DatabaseItemType& m_rData;                                                    static std::map<std::string,DatabaseItemType> g_oSharedDatabase;};template<typename T>std::map<std::string,typename SharedDataHolder<T>::DatabaseItemType> SharedDataHolder<T>::g_oSharedDatabase ;#endif

这个方法的优点是:

1) 很方便就可以在模块中共享数据;

2) 有多线程时,可以比较方便地现对这些共享数据读写;

3) 是类型安全的;

4) 简单。

缺点也是有的:

1) 使用了全局变量;

2) 对数据的保护力度不够,在其他模块也可以到这些数据,这也许不算个缺点,因为我们需要在不同的模块之间传递数据。

扩展:

1)StorePolicy对于枚举类型也应该采用存值的方式;

2) 在SharedDataHolder中加上更多的方法(比如赋值,== ,!=等);

3)同步ShareDataHolder多线程读写操作.
原文链接: https://www.cnblogs.com/li_shugan/archive/2010/12/10/1901641.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/18624

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午7:27
下一篇 2023年2月7日 下午7:28

相关推荐