2

我正在设计一个基于生产者/消费者的应用程序,并且我坚持在类表示中表示生产者生成的任务。

实际的问题是这样的:生产者可以生产StandaloneTask一个消费者可以直接消费的产品,或者它可以生产一个CompressTask必须经过第一个的产品,然后将TaskDecompressor其首先提取成许多StandaloneTask消费者可以消费的产品。

StandaloneTask由于和之间有很多共性CompressTask,所以我创建了一个名为的基类TaskBase,其中包含所有这些通用信息。

class abstract TaskBase 
{

}

class StandloneTaskType1: TaskBase
{

}

class StandloneTaskType2: TaskBase
{

}

.
.
.

class StandloneTaskTypeN: TaskBase
{

}

任务的解压如何工作?一个任务可以有一个或多个需要在运行时填写的参数。压缩任务由一个带有参数的任务和有关如何获取需要在这些参数中填充的值的其他信息组成。获取值后,TaskDecompressor假设将所有这些值填充到参数化任务中以生成一个或多个独立任务。

我创建了一个CompressTask类如下。

class CompressTask: TaskBase
{
    TaskBase task;

    //runtime parameters
}

CompressTask现在,它的派生自它对我来说看起来很奇怪,TaskBase它还包含一个TaskBase. 有这样的课是正确的吗?或者有没有更好的给定案例的类表示。

4

4 回答 4

3

总体而言,这种结构并不少见,您开始走上复合模式的道路。您CompressTask的行为有点像 Composite,而您StandaloneTask的行为就像 Leaf。

我建议阅读该设计模式,并可能考虑让消费者更容易使用 TaskBase 的任何子类,无论它是 aCompressTaskStandaloneTask. 这将加强您的设计并简化消费。

于 2013-01-13T06:35:45.703 回答
1

想象...

class Student: Person
{
    Person father;
    Person mother;
    Date dateOfEnrollment;
}

这完全有道理不是吗?原则上,您的 CompressTask 类没有任何问题。

于 2013-01-13T06:47:58.897 回答
0

一个重要的 OO 设计规则:优先组合而不是实现继承。仅仅因为StandaloneTaskCompressTask有许多共性并不能让它成为一个好的选择让它们共享相同的基类。如果两个类共享一些接口,建议通过使用接口继承来分解接口。如果两个类共享一些实现,你最好将实现分解到某个类中,并将其嵌入到上述两个类中(即组合)。

回到你的例子,它CompressTask是派生自TaskBase并且它还包含一个 TaskBase 的实例。这意味着您同时使用实现继承和组合,这听起来不太好。以下骨架仅供您参考:

interface Task
{
    // some common Task interface here...
}

class TaskImpl
// Or: class TaskImpl : Task // depends on your needs
{    
    // some common Task-related implementation here...
}

class CompressTask: Task // interface inheritance, NOT implementation inheritance
{
    TaskImpl taskImpl; // contains *reusable* task-related implementation
    Task task;  // contains the target task(s) to be compressed
    // other code...
}

class StandloneTaskType1: Task
{
    TaskImpl taskImpl;
    // other code...
}

.
.
.

class StandloneTaskTypeN: Task
{
    TaskImpl taskImpl;
    // other code...
}
于 2013-01-13T06:40:38.807 回答
0

更好的是......想象一下......

class Foo // implicitly extends Object
{
    String name; // also a direct subclass of Object (at least in Java anyway)
    Integer age; // extends Number, which extends Object (at least in Javaland)
    Object theRootOfAllEvil; // a raw instance of the superclass
    int i; // the only member that is not an Object
}

请原谅我的爪哇语,但我来自哪里都没有错;)

这一切都取决于你的课程的细节。

于 2013-01-13T08:05:19.703 回答