我有以下'实体'在我的模型中:DataItem
,String
,Integer
和Argument
。
我不确定如何创建一个反映以下方面的类图:
String
是DataItem
Integer
是DataItem
Argument
可以是String
,Integer
或DataItem
(即String
也不Integer
}。我是否必须创建其他类" StringArgument"," IntegerArgument"和" DataItemArgument"还是有更好的解决方案?我假设从String
,Integer
和DataItem
继承Argument不是一个好的解决方案,对吗?
一般情况下:我如何为一个类从一个类或另一个类继承的案例建模?
PS:实现将在Python 2.7中,但我对一般问题感兴趣,所以任何引用其他语言的解决方案都可以。
答案 0 :(得分:1)
在我看来,你的通用类是Argument
,而你的其他三个类应该继承它。
这确实需要String
和Integer
的包装类。
你的问题让我想起了复合设计模式,但我不确定它是否是你想要的。
答案 1 :(得分:1)
一种方法是将Argument
概念与数据项的概念分开。您String
和Integer
都是DataItem
,这是对的,但我不相信Argument
是DataItem
。它只有一个。这自然导致:
DataItem
^ ^
/ \
| |
String Integer
并且Argument
会将指针或引用(或实现语言支持的任何内容)保存到DataItem
。参数可能不仅包含(一个)数据(项目);例如,如果它是程序的命令行参数,您可能希望保留位置信息。因此,对我来说,参数包含数据,而不是参数 数据。
class Argument {
public:
// etc
private:
DataItem* data;
};
(请注意,这种方法可以在大多数支持面向对象编程的语言中实现。)
您可以将StringArgument
和IntegerArgument
作为单独的类型,保留相关类型的成员,但这样做的相关性将根据情况和实现语言而有所不同(例如,在Python中) ,你不会关心它是Integer
还是String
,只要它订阅DataItem
规定的接口即可。在C ++中,您可以使用模板将Argument
类作为通用容器提供:
template <typename data_type>
class Argument {
public:
// etc.
private:
data_type data;
};
typedef Argument<String> StringArgument; // "composes a" String
typedef Argument<Integer> IntegerArgument; // "composes an" Integer
换句话说,确切地说,如何实现这一点将取决于您选择的语言提供的设施,但如果您不认为参数是&#34;一种&#34;设计更简单;数据,而不是数据的容器(或持有者)&#34;。
作为另一个例子,再次在C ++中,您可以从相关数据类型继承Argument
类型...
template <typename data_type>
class Argument : public data_type {
// etc.
};
typedef Argument<String> StringArgument; // "is a" String
typedef Argument<Integer> IntegerArgument; // "is an" Integer
(请注意,这种方法需要一种语言来支持泛型编程,在某种意义上类似于C ++模板)。
这可以追溯到是数据的概念,而不是包含数据。