一個快速思想:
1)複合物和原子態( 「A」, 「B」, 「C」 作爲observees和 「A」 作爲觀察者,等等之間觀察者模式..)
2)使用Pimpl idiom實現class-A來分離接口&實現細節,從而具有更多的控制權,並且在更改實現細節方面展現出更多的靈活性。
3)讓A類具有某種工廠抽象來創建&爲每個唯一狀態「A」管理專門的實現對象。 4)因此,只要a,b,c上的變化被「A」觀察到,Factory就會幫助檢索「A」的相應實現狀態並進行狀態變化。 在「A」和「X」之間應用相同的方法。
更詳細的佈局:
1)定義所需的接口(通用或抽象類)IX,IA,IA,IB,IC。
2)在界面IA,定義公共IaChanged式(Ia *),IbChanged(IB *)& IcChanged(IC *)方法來接收IA,IB & Ic的狀態變更通知(觀察者模式的回調方法)。
3)在原子界面Ia內部,Ic。Ic。定義公共註冊表(IA &)& private Notify()metods。 在接口1a中,
Where Notify() { foreach(observer in m_Observers)
observer->IaChanged(this);
}
在接口1b中,
Where Notify() { foreach(observer in m_Observers)
observer->IbChanged(this);
}
等等...
4)具有clases X,A,從各自的接口得到的,B,C。其中 - >代表「衍生」。其中 - >代表「衍生」。 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)具有用於每個不同狀態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管理生命週期,定義一些typedefs易於使用。
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級
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」當前狀態
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;
}
看看http://www.complang.org/ragel/ – akira 2013-02-28 06:36:13
它看起來非常interes但這並不能解決這個問題,因爲各州之間的過渡還不得而知 - 我們只能在發生狀態變化後才能觀察到狀態變化,並據此調整上層狀態。 – awishformore 2013-02-28 14:30:07
你不知道如何從一個狀態轉換到另一個狀態?我的意思是,如果你處於'狀態',然後發生了事情,然後你處於'狀態A',你測量了一些標記當前狀態爲'A'的東西。所以,在那裏你有你已知的狀態改變者......你觀察到的東西。 – akira 2013-02-28 19:02:12