如何建模和实现可能继承自不同 classes 的 class?
How to model and implement a class that may inherit from different classes?
我的模型中有以下 'entities':DataItem
、String
、Integer
和 Argument
。
我不确定如何创建反映以下方面的 class 图:
- 一个
String
是一个DataItem
- 一个
Integer
是一个DataItem
Argument
可以是 String
、Integer
或 DataItem
(即既不是 String
也不是 Integer
)。
我必须创建额外的 类 "StringArgument"、"IntegerArgument" 和 "DataItemArgument" 还是有更好的解决方案?我认为让 Argument 继承自 String
、Integer
和 DataItem
不是一个好的解决方案,对吧?
一般情况:如何对 class 从一个 class 或另一个 class 继承的情况建模?
PS:实现将在 Python 2.7 中,但我对一般问题感兴趣,因此任何引用其他语言的解决方案都可以。
在我看来,您的通用 class 是 Argument
,而您的其他三个 class 应该继承它。
这确实需要 String
和 Integer
的包装器 classes。
你的问题让我想起了Composite Design Pattern,但是不知道是不是你想要的
一种方法是将 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
class 作为通用容器:
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
换句话说,具体如何实现将取决于您选择的语言提供的功能,但如果您不将参数视为 "a kind of" 数据,设计会更简单,而是成为 "a container (or holder) of data".
再举一个例子,在 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++ 模板的泛型编程)。
这可以追溯到参数 是 数据而不是包含数据的想法。
我的模型中有以下 'entities':DataItem
、String
、Integer
和 Argument
。
我不确定如何创建反映以下方面的 class 图:
- 一个
String
是一个DataItem
- 一个
Integer
是一个DataItem
Argument
可以是String
、Integer
或DataItem
(即既不是String
也不是Integer
)。
我必须创建额外的 类 "StringArgument"、"IntegerArgument" 和 "DataItemArgument" 还是有更好的解决方案?我认为让 Argument 继承自 String
、Integer
和 DataItem
不是一个好的解决方案,对吧?
一般情况:如何对 class 从一个 class 或另一个 class 继承的情况建模?
PS:实现将在 Python 2.7 中,但我对一般问题感兴趣,因此任何引用其他语言的解决方案都可以。
在我看来,您的通用 class 是 Argument
,而您的其他三个 class 应该继承它。
这确实需要 String
和 Integer
的包装器 classes。
你的问题让我想起了Composite Design Pattern,但是不知道是不是你想要的
一种方法是将 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
class 作为通用容器:
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
换句话说,具体如何实现将取决于您选择的语言提供的功能,但如果您不将参数视为 "a kind of" 数据,设计会更简单,而是成为 "a container (or holder) of data".
再举一个例子,在 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++ 模板的泛型编程)。
这可以追溯到参数 是 数据而不是包含数据的想法。