对于具有共同祖先和共同后代的不同类,我应该选择什么设计模式?
What design pattern should I choose for different classes with common ancestor and common descendants?
我目前正在重构我的一些代码。我有两个——大部分是多余的——单元,每个产品一个。两者都包含一个继承了几个子class的基class。它们也继承了更多子classes。
现在我想合并两个单元,让冗余代码不再冗余,不同的部分在两个不同的单元中分别实现。
我首先想到的是像下面这样的层次结构:
BaseClass
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
Product<A>BaseClass Product<B>BaseClass
\ /
\ /
\ /
\ /
\ /
\ /
\ /
\ /
\ /
\ /
X
/|\
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
SubClass<1> SubClass<2> SubClass<3>
/ \ |
/ \ |
/ \ |
/ \ |
/ \ |
/ \ |
/ \ |
SubClass<1.1> SubClass<1.2> SubClass<3.1>
但问题是 X
,其中继承连接在特定于产品的 classes 之下,因为这种继承在 Delphi 语言中是不可能的。
所以,我认为必须有一个设计模式,它对于实现具有共同父 class 和共同后代 classes?
的模型很有用
编辑: 我制作了一个 UML class 图来阐明当前情况。
Now I want to merge both units, so that redundant code won't be redundant anymore and differing parts are implemented separately in two different units.
如果 A
和 B
是 BaseClass
的后裔,并且每个人都有 某些东西 的共同点(你的 X),那么你应该意识到某物 应该是 BaseClass
的一部分。这就是您的解决方案,真的就是这么简单。
如果 A
和 B
将执行委托给外部代码(带有事件、回调例程等...),而这些代码在不知不觉中恰好是相同的代码,那么就好了。
没有看到你的实际 classes 也不知道你想要实现什么,很难给出答案,因为有很多考虑因素。
像 C++ 那样的真正的多重继承是不可能的。您可以对接口做一些类似的事情,但这在这里似乎不合适,因为您没有指出任何 classes 仅从 A 或 B 派生,因此如果您实现它们,您将不得不移动所有实际的函数定义无论如何到X。
但是 X 是什么?从逻辑上考虑。例如,如果 A 是水果,B 是圆形,X 是橙子,那么正如 NGLN 所说,您需要将 A 和 B 合并到 X(或 BaseClass)中,然后扔掉 A 和 B。
另一方面,如果 A 是汽油箱、B 车头灯和 X 汽车,则 X 将包含两个 class 成员 A 和 B,而 subclasses 将引用这些成员.
另一方面,如果实际上有 classes 仅从 A 和 B 派生,那么您可以选择使用接口并接受这样一个事实,即某些实现可能必须在A(并分别在 B 中)和 X 中,或者,也许等价地,从 baseclass 派生 X 并在 X 中复制 B 和 C 的函数。最后两个选项都不是理想的,您可以选择无论如何合并它们并从 X 派生所有内容,无论它是真的来自 A 还是来自 B。
我将详细说明 NGLN 在他的回答中所解释的内容,因为考虑到您提供的信息,这似乎是最好的回答。
考虑以下 class 模型作为您可能的解决方案:
TProduct = class
// Declarations for any product
end;
TProductA = class(TProduct)
// Declarations for any products of kind A
end;
TProductB = class(TProduct)
// Declarations for any products of kind B
end;
TProductA1 = class(TProduct)
// Declarations for product A1
end;
TProductA2 = class(TProduct)
// Declarations for product A2
end;
TProductB1 = class(TProduct)
// Declarations for product B1
end;
// Other product declarations
除非你有其他复杂的情况,否则这似乎就是你所需要的!
我目前正在重构我的一些代码。我有两个——大部分是多余的——单元,每个产品一个。两者都包含一个继承了几个子class的基class。它们也继承了更多子classes。
现在我想合并两个单元,让冗余代码不再冗余,不同的部分在两个不同的单元中分别实现。
我首先想到的是像下面这样的层次结构:
BaseClass
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
/ \
Product<A>BaseClass Product<B>BaseClass
\ /
\ /
\ /
\ /
\ /
\ /
\ /
\ /
\ /
\ /
X
/|\
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
/ | \
SubClass<1> SubClass<2> SubClass<3>
/ \ |
/ \ |
/ \ |
/ \ |
/ \ |
/ \ |
/ \ |
SubClass<1.1> SubClass<1.2> SubClass<3.1>
但问题是 X
,其中继承连接在特定于产品的 classes 之下,因为这种继承在 Delphi 语言中是不可能的。
所以,我认为必须有一个设计模式,它对于实现具有共同父 class 和共同后代 classes?
的模型很有用编辑: 我制作了一个 UML class 图来阐明当前情况。
Now I want to merge both units, so that redundant code won't be redundant anymore and differing parts are implemented separately in two different units.
如果 A
和 B
是 BaseClass
的后裔,并且每个人都有 某些东西 的共同点(你的 X),那么你应该意识到某物 应该是 BaseClass
的一部分。这就是您的解决方案,真的就是这么简单。
如果 A
和 B
将执行委托给外部代码(带有事件、回调例程等...),而这些代码在不知不觉中恰好是相同的代码,那么就好了。
没有看到你的实际 classes 也不知道你想要实现什么,很难给出答案,因为有很多考虑因素。
像 C++ 那样的真正的多重继承是不可能的。您可以对接口做一些类似的事情,但这在这里似乎不合适,因为您没有指出任何 classes 仅从 A 或 B 派生,因此如果您实现它们,您将不得不移动所有实际的函数定义无论如何到X。
但是 X 是什么?从逻辑上考虑。例如,如果 A 是水果,B 是圆形,X 是橙子,那么正如 NGLN 所说,您需要将 A 和 B 合并到 X(或 BaseClass)中,然后扔掉 A 和 B。
另一方面,如果 A 是汽油箱、B 车头灯和 X 汽车,则 X 将包含两个 class 成员 A 和 B,而 subclasses 将引用这些成员.
另一方面,如果实际上有 classes 仅从 A 和 B 派生,那么您可以选择使用接口并接受这样一个事实,即某些实现可能必须在A(并分别在 B 中)和 X 中,或者,也许等价地,从 baseclass 派生 X 并在 X 中复制 B 和 C 的函数。最后两个选项都不是理想的,您可以选择无论如何合并它们并从 X 派生所有内容,无论它是真的来自 A 还是来自 B。
我将详细说明 NGLN 在他的回答中所解释的内容,因为考虑到您提供的信息,这似乎是最好的回答。
考虑以下 class 模型作为您可能的解决方案:
TProduct = class
// Declarations for any product
end;
TProductA = class(TProduct)
// Declarations for any products of kind A
end;
TProductB = class(TProduct)
// Declarations for any products of kind B
end;
TProductA1 = class(TProduct)
// Declarations for product A1
end;
TProductA2 = class(TProduct)
// Declarations for product A2
end;
TProductB1 = class(TProduct)
// Declarations for product B1
end;
// Other product declarations
除非你有其他复杂的情况,否则这似乎就是你所需要的!