一个快速的想法:
1)复合和原子状态之间的观察者模式(“a”,“b”,“c”作为观察者,“A”作为观察者,等等..)
2) 使用 Pimpl idiom 实现 class-A 以分离接口和实现细节,从而在更改实现细节方面拥有更多控制权并表现出更灵活。
3)让A类有某种工厂抽象来为“A”的每个独特状态创建和管理专门的实现对象。
4) 因此,每当“A”观察到 a、b、c 的变化时,Factory 都会帮助检索“A”的相应实现状态并进行状态更改。在“A”和“X”之间应用相同的方法。
更详细的布局:
1) 定义所需的接口(通用或抽象类)IX、IA、Ia、Ib、Ic。
2) 在接口 IA 中,定义 public IaChanged(Ia*), IbChanged(Ib*) & IcChanged(Ic*) 方法来接收 Ia, Ib & Ic 状态变化通知(观察者模式的回调方法)。
3) 在原子接口 Ia、Ib 和 Ic 内部。定义公共 Register(IA&) 和私有 Notify() 方法。在界面 Ia 中,
Where Notify() { foreach(observer in m_Observers)
observer->IaChanged(this);
}
在界面 Ib 中,
Where Notify() { foreach(observer in m_Observers)
observer->IbChanged(this);
}
很快...
4) 具有从各自接口派生的类 X、A、a、b、c。X->IX, A->IA, a->Ia, b->Ib & c->Ic,其中->代表“衍生”。
5) 让 A 类定义 A_implState (Pimpl Idiom),其中 A_implState 可以派生自新接口 IA_implState 以保持通用性。
将类 A_implState0、A_implState1、A_implState2、A_implStateX 作为 IA_implState 的专用版本。
在哪里,
class IA_implState
{
public:
virtual void processStateChange()=0;
};
class A_implState0 : public IA_implState
{
public:
void processStateChange()
{
// do your stuff specific to State "0" of "A".
}
};
class A_implStateX : public IA_implState
{
public:
void processStateChange()
{
// do your stuff specific to State "X" of "A".
}
};
so on...
6) 对 A 的每个不同状态有一个 IA_Impl 特化,基于:
a b c - A
0 0 0 - 0
1 0 0 - 1
2 0 0 - x
2 1 0 - 2
7) 在 A 类中,每当 IaChanged(IaPtr) 或 IbChanged(IbPtr) 或 IcChanged(IcPtr) 被相应的被观察者触发时,将更改通知处理为:
// a changed
void A::IaChanged(IaPtr a)
{
//Buffer Ia inside a member
m_pIa = a;
//Retrieve A-implementer based on the current state.
m_pimplA = m_implAContainer[GetCurrentState()]; // or use FactoryMethod or AbstractFactory pattern if required.
m_pimplA->processStateChange();
}
// b changed
void A::IbChanged(IbPtr b)
{
//Buffer Ib inside a member
m_pIb = b;
m_pimplA = m_implAContainer[GetCurrentState()]; // use FactoryMethod or AbstractFactory pattern if required.
m_pimplA->processStateChange();
}
/* 一个粗略的草图,可能看起来像 */
使用 shared_pointers 来管理生命周期,定义一些 typedef 以便于使用。
typedef std::shared_ptr<Ia> IaPtr;
typedef std::shared_ptr<Ib> IbPtr;
typedef std::shared_ptr<IA_impl> IAImplPtr;
typedef std::map<int /* or other datatype as required */ , IA_implPtr> ImplAPtrContainer;
// class-A may look like
class A : public IA
{
public:
void IaChanged(const IaPtr ptr_a);
void IbChanged(const IbPtr ptr_b);
void Init();
void DeInit() { m_implAContainer.clear(); }
private:
int GetCurrentState();
private:
ImplAPtrContainer m_implAContainer;
IAImplPtr m_pimplA;
IaPtr m_aPtr;
IbPtr m_bPtr;
IcPtr m_cPtr;
};
// 使用 A 类的所有可能实现状态初始化 Container
void A::Init()
{
m_implAContainer.insert(/*state*/ 0, IAImplPtr(new A_implState0));
m_implAContainer.insert(/*state*/ 1, IAImplPtr(new A_implState1));
m_implAContainer.insert(/*state*/ X, IAImplPtr(new A_implStateX));
}
// 根据a,b & c'当前状态判断A的当前状态
int A::GetCurrentState()
{
// Have this method return A's state based on a b c, prefer enums over magic numbers
if(m_aPtr->GetState() == 0 && m_bPtr->GetState() == 0 && m_cPtr->GetState() == 0)
return 0;
}