我正在編寫DAL/ORM庫。該庫將主要從GUI訪問,但也可以從一些「業務級別」應用程序訪問。我仍然處於這個庫的設計階段,並且我不確定如何很好地解決以下問題。從基類指針訪問派生類成員的設計替代方案
在我目前的設計中,我有一堂課,暫時稱之爲List
,它有另一個班級的容器,Properties
。屬性有兩種風格(A和B),大多具有相同的功能,但其中一些功能是不同的。此外這兩種口味的Properties
商店價值。值可以是不同的數據類型,包括但不限於POD。每個List
可以包含某個Property
只有一次,並且Properties
由「名稱」即字符串標識。
我現在希望能夠做到以下所有:
- 保持界面的複雜性儘可能低
- 迭代中
List
所有Properties
,並調用方法,無論Property
口味支持。 - 有
Property
的實例時,訪問一個類型的值安全的方式 - 如果可能,避免
dynamic_cast
或類似的結構
所以,很明顯純多態性不能在這裏做的伎倆。我做了一些實驗與奇異遞歸模板模式與組成兩級層次 - 一個用於Properties
,一個用於它們的值(以下示例代碼)。但是,到目前爲止,我沒有成功實現滿足我所有要求的設計。
的基本設計(即哪些類存在,它們是如何組織等)是不固定的,並且可以容易地改變。我仍然處於這個項目的設計階段,所以只有測試代碼存在。然而,基本思想必須像上面解釋的那樣(即List
具有Properties
,其又具有values
)。
任何解決我的問題或原始的想法,想法等都受到高度讚賞。
層次結構實現的示例代碼。很明顯,我無法在這裏以類型安全的方式訪問屬性的值。
class PropertyValue {
public:
virtual std::string GetAsString() const = 0;
bool IsReadOnly() const { return m_isReadOnly; }
void IsReadOnly(const bool val) { m_isReadOnly = val; }
protected:
PropertyValue(PropertyValue & other) : m_isReadOnly(other.m_isReadOnly)
{};
PropertyValue(bool readOnly) : m_isReadOnly(readOnly)
{};
private:
bool m_isReadOnly;
};
class StringValue : public PropertyValue {
private:
typedef std::string inner_type;
public:
StringValue(const inner_type & value, bool readOnly) : PropertyValue(readOnly)
, m_value(value)
{};
StringValue(StringValue & other) : PropertyValue(other.IsReadOnly())
, m_value(other.m_value)
{};
std::string GetAsString() const { return m_value; };
inner_type GetValue() const { return m_value; };
void SetValue(const inner_type & value) { m_value = value; };
unsigned int GetMaxLenght() const { return m_maxLength; };
private:
inner_type m_value;
unsigned int m_maxLength;
};
class IntValue : public PropertyValue {
private:
typedef int inner_type;
public:
IntValue(const inner_type & value, bool readOnly) : PropertyValue(readOnly)
, m_value(value)
{};
IntValue(IntValue & other) : PropertyValue(other.IsReadOnly())
, m_value(other.m_value)
{};
std::string GetAsString() const { char tmp[((CHAR_BIT * sizeof(int))/3 + 1)]; return itoa(m_value, tmp, 10); };
inner_type GetValue() const { return m_value; };
void SetValue(const inner_type & value) { m_value = value; };
int GetMinValue() const { return m_minValue; };
int GetMaxValue() const { return m_maxValue; };
private:
inner_type m_value;
int m_minValue;
int m_maxValue;
};
class Property {
public:
Property(std::auto_ptr<PropertyValue> value, bool visible)
{
m_value = value;
m_isVisible = visible;
}
bool IsVisible() const { return m_isVisible; }
void IsVisible(const bool val) { m_isVisible = val; }
std::string GetValueAsString() const { return m_value->GetAsString(); };
const PropertyValue & getValue() const { return (*m_value.get()); }
private:
std::auto_ptr<PropertyValue> m_value;
bool m_isVisible;
};
class PropertyFlavorA : public Property {
public:
PropertyFlavorA(std::auto_ptr<PropertyValue> value, bool visible) : Property(value, visible)
{
value->IsReadOnly(true);
};
};
class PropertyFlavorB : public Property {
public:
PropertyFlavorB(std::auto_ptr<PropertyValue> value, bool visible) : Property(value, visible) {};
};
真正的問題是你怎麼想訪問值。你只是在GUI中暴露他們嗎?當你有「鑰匙」時,你知道「價值」類型嗎? – IdeaHat
我在寫DAL/ORM。所以是的GUI是將使用我的圖書館的主要領域。我沒有真正的鍵值對。然而,我可以通過某種關鍵字來告訴數據類型 – sigy