【发布时间】:2014-02-18 16:18:34
【问题描述】:
我正在编写一个 DAL/ORM 库。该库将主要从 GUI 访问,但也从一些“业务级”应用程序访问。我仍处于这个库的设计阶段,到了不知道如何很好地解决以下问题的地步。
在我目前的设计中,我有一个类,我们暂时称它为List,它有另一个类的容器Properties。属性有两种风格(A 和 B),它们的功能大部分相同,但它们的某些功能不同。此外,Properties 的两种风格都存储值。值可以是不同的数据类型,包括但不限于 POD。每个List 只能包含某个Property 一次,Properties 由“名称”标识,即字符串。
我现在希望能够执行以下所有操作:
- 尽可能降低接口的复杂性
- 遍历
List中的所有Properties,并调用Property两种风格都支持的方法。 - 当拥有
Property的实例时,以类型安全的方式访问其值 - 如果可能,请避免使用
dynamic_cast或类似结构
所以,显然纯多态在这里不能解决问题。我已经对奇怪地重复出现的模板模式和两个类层次结构的组合做了一些实验——一个用于Properties,一个用于它们的值(下面的示例代码)。但是,到目前为止,我还没有成功地获得满足我所有要求的设计。
基本设计(即存在哪些类、它们的组织方式等)不是固定的,可以轻松更改。我还在这个项目的设计阶段,所以只有测试代码存在。但是,基本思想必须像上面解释的那样(即List 具有Properties,而values 又具有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 中公开它们吗?当你有一个“键”时,你知道“值”类型吗?
-
我正在写一个 DAL/ORM。所以是的,GUI 是使用我的库的主要域。我没有真正的键值对。但是,我可以通过某种键告诉值数据类型
标签: c++ design-patterns inheritance derived-class crtp