Java设计帮助。继承和共享代码

Java设计帮助。继承和共享代码,java,oop,Java,Oop,我在编程开发方面仍然有点无所事事,在设计一个干净的设计时遇到了一些麻烦。具体来说,我有一个场景如下: 我有4个类,每个类都有共同的功能。让我们调用这些方法A、B、C等 类别:会计科目;方法:A、B、C、G、H、I、S1、S2、S3 类别:文件夹;方法:A、B、C、D、E、S1、S2、S3 类别:组;方法:A、B、C、D、E、F、S1、S2、S3 类别:角色;方法:A、B、C、D、E、F、S1、S2、S3 上面指定的方法是抽象的。如中所示,可能有一个FooAccount和一个BarAccount以

我在编程开发方面仍然有点无所事事,在设计一个干净的设计时遇到了一些麻烦。具体来说,我有一个场景如下:

我有4个类,每个类都有共同的功能。让我们调用这些方法A、B、C等

类别:会计科目;方法:A、B、C、G、H、I、S1、S2、S3
类别:文件夹;方法:A、B、C、D、E、S1、S2、S3
类别:组;方法:A、B、C、D、E、F、S1、S2、S3
类别:角色;方法:A、B、C、D、E、F、S1、S2、S3

上面指定的方法是抽象的。如中所示,可能有一个FooAccount和一个BarAccount以不同的方式实现方法。但是,FooAccount和FooGroup具有相同的方法A(因为它们具有相同的实现;Foo)。还不错,除了有些方法S1、S2和S3在Foo和Bar之间实现相同之外,因此fooccount和BarAccount具有相同的方法S1、S2和S3

目前我的设计很难看:

接口对象1:声明A、B、C
接口对象2扩展了对象1:声明D,E
接口对象3扩展了对象2:声明F
接口帐户扩展Object1:声明G、H、I
接口文件夹扩展了Object2
接口组扩展Object3
接口角色扩展Object3
类帮助器:定义S1、S2、S3

我知道有充分的理由禁止多重继承,但如果允许我这样做,我可以将方法S1、S2和S3放入Object1,并将所有接口转换为抽象。然后FooAccount可以扩展Account和FooObject1


谁能给我一些建议,什么样的结构可能更好?我是否应该将所有A、B、C等放在一个Util类中(例如FooUtil和BarUtil)?

您应该根据角色而不是发生情况对接口中的方法进行分组。因此,假设
A
B
C
属于一个角色,
D
E
属于另一个角色,
F
属于它自己

interface Role1 - A, B, C
interface Role2 - D, E
interface Role3 - F
interface Account extends Role1
interface Folder extends Role1, Role2
interface Group extends Role1, Role2, Role3
如果有方法的通用实现,可以将它们移动到提供默认实现的抽象基类

abstract class Helper - S1, S2, S3
然后您可以声明您的具体类

class FooAccount extends Helper implements Account

您可以考虑使用泛型,如果您可以提取与<代码> FoO 和 BAU>代码>相同的行为,并具有<代码>帐户是一个泛型类(使用<代码> FooBar < /C> >,而不是接口

不依赖继承作为减少重复代码的机制。相反,找出一种方法将责任划分为不同的类

FooAccount和FooGroup具有相同的方法A


这告诉我方法A的实现属于它自己的类(
FooA
)。如果
Account
Group
公开方法
A
确实有意义,那么
FooAccount.A
FooGroup.A
的实现应该只是传递给
FooA.A

谢谢你的回答,但除非我弄错了,因为Account/Group只是接口,我必须在每个类中显式地写出方法A。我正试图尽可能减少重复代码…@kennyg-如果你有方法的通用实现,你可以将它们模式化为一个抽象类,然后从中继承(参见
Helper
的示例——您当然可以创建更多此类Helper抽象基类,以提供
A
B
C
的通用实现)。但在您的设计中,共享围绕
Foo
Bar
(所有
Foo*
类都有相同的
A
,所有
Bar*
类都有相同的
A
(这与
Foo*
对应的类不同)),[cont.][cont.]您应该在
Foo
中实现
A
(还有
Bar
)类传递给
帐户
等实现,这些实现将调用传递的对象的
方法。这样,实现就足够通用,您也可以轻松地提出
FooBar
类,并且仍然正确地捕获共享代码。您是否可以进一步了解pa的详细信息ss-through's?你是说FooAccount.A只是调用FooA.A吗?@kennyg:没错。在我看来,一个简单的方法调用并不违反DRY原则。你想要避免重复的真正逻辑将驻留在FooA.A中,因此如果你的其他类为了你的API而需要实现这个方法,他们可以将责任委托给你o FooA类。