在我们的工作中经常遇到这样的情况: 当一个值改变后,需要更新些与此值相关的其它数据或界面.
解决这个问题的经典方法是设计模式里的各种模式,比如观察者模式等等.
要想使用模式就需要提升抽象的层次,而提升抽象的层次就需要加进间接层,这点毋容置疑.
我使用的是另一种方法,也是观察者模式,尽量少的加进间接层,而是很硬朗的方式,也能工作,所以此帖的标题中就有"VS"(可是我知道我的实现自然没有GOF的设计模式的好,我有自知之明;但不能因为有设计模式就没有自己的个性方案了,我们也需要思考要是自己改怎么做,这就是多态~)
下面就是我的解决方案:
template<typename ValueType>
class Data
{
public:
Data()
{
m_mapUpdate.clear();
}
~Data()
{}
void Update()
{
for (map<unsigned long,unsigned long>::const_iterator citer=m_mapUpdate.begin()
;citer!=m_mapUpdate.end()
;++citer)
{
void* pv = &m_Value;
_asm
{
mov eax,dword ptr[pv];
push eax;
mov ecx,dword ptr[citer->first];
call dword ptr[citer->second];
}
}
}
ValueType GetData()
{
return m_Value;
}
void SetData(const ValueType& Value,bool IsUpdate = false)
{
m_Value = Value;
if (IsUpdate)
Update();
}
template<typename ClassType,typename MFType>
void Insert(ClassType* pv,MFType pMF)
{
if (m_mapUpdate.find(pv) != m_mapUpdate.end())
return ;
unsigned long* pAddr = reinterpret_cast<unsigned long*>(&pMF);
unsigned long ulAddr = *pAddr;
unsigned long ulObj = reinterpret_cast<unsigned long>(pv);
m_mapUpdate.insert(::make_pair<unsigned long,unsigned long>(ulObj,ulAddr));
}
map<unsigned long,unsigned long> m_mapUpdate;
private:
ValueType m_Value;
};
使用:
Data<unsigned long> ulData;
ulData.insert(需要更新的对象地址,需要更新的对象的成员函数偏移);
ulData.SetData(2000,true);