2014-02-18 85 views
0

我正在編寫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) {}; 
}; 
+0

真正的問題是你怎麼想訪問值。你只是在GUI中暴露他們嗎?當你有「鑰匙」時,你知道「價值」類型嗎? – IdeaHat

+0

我在寫DAL/ORM。所以是的GUI是將使用我的圖書館的主要領域。我沒有真正的鍵值對。然而,我可以通過某種關鍵字來告訴數據類型 – sigy

回答

0

我終於決定在我的List類中使用boost::variant這個向量。我Property類現在是一個模板類,其中模板參數進行實例化一個ValueType類的子類。 Properties的不同口味源自Property類。

現在看來,這種做法滿足了我所有的初始要求:

  • 它使界面低的複雜性✓
  • 遍歷所有PropertiesList,並調用方法,無論Property口味支持是可以使用std::for_eachboost::apply_visitor
  • 如果有一個Property的實例,以類型安全的方式訪問其值如果我的Property基類允許訪問其ValueType成員。 ✓不需要✓

  • 使用dynamic_cast的或類似的結構對這種做法有任何意見仍然讚賞。

  • 1

    你似乎已經回答了你自己的問題...

    迭代中List所有Properties,並調用方法,無論Property口味的支持。

    這是polymorphism

    Properties的這兩種風味都有一個基類,它有一個虛擬函數,您的A類和B類Property類將被覆蓋。然後可以從存儲在List中的基類指針調用該函數。

    +0

    我熟悉多態性。但是多態性不允許我以類型安全的方式訪問屬性的值。請記住它們是不同的類型。即使同一種財產的味道可以有不同的價值類型。 – sigy

    +0

    @sigy:夠公平的,你能給我們一個你的'財產'的例子(我認爲是類?)。你可以使你的'Property'類有點像[Variant數據類型](http://msdn.microsoft.com/en-us/library/dd338762.aspx)? – parrowdice

    相關問題