kennyg
kennyg

Reputation: 1059

Java design help. Inheritance and sharing code

I'm still a bit of a noobie in programming development and am having some trouble with making a clean design. Specifically, I have a scenario as below:

I have 4 classes, each with common functionality. Lets call these methods A, B, C, etc.

class: Account ; methods: A, B, C, G, H, I, S1, S2, S3
class: Folder; methods: A, B, C, D, E, S1, S2, S3
class: Group ; methods: A, B, C, D, E, F, S1, S2, S3
class: Role ; methods: A, B, C, D, E, F, S1, S2, S3

The methods specified above are abstract. As in there could be a FooAccount and a BarAccount which implement method A differently. However FooAccount and FooGroup have the same method A (since they are of the same implementation; Foo). Not too bad, except there are also some methods S1, S2 and S3 that are implemented identically even between Foo and Bar so that FooAccount and BarAccount have identical methods S1, S2 and S3.

Currently my design is quite ugly:

interface Object1: declares A, B, C
interface Object2 extends Object1: declares D, E
interface Object3 extends Object2: declares F
interface Account extends Object1: declares G, H, I
interface Folder extends Object2;
interface Group extends Object3;
interface Role extends Object3;
class Helper: defines S1, S2, S3

I know multiple inheritances are prohibited for good reason, but if I were allowed to do so I could put the methods S1, S2, and S3 into Object1 and turn all the interfaces into abstracts. Then FooAccount could extend both Account and FooObject1.

Can anyone give me some advice to what structure might be better? Should I just put all A, B, C, etc. into a Util class (e.g. FooUtil and BarUtil)?

Upvotes: 4

Views: 165

Answers (2)

StriplingWarrior
StriplingWarrior

Reputation: 156624

Don't rely on inheritance as a mechanism to reduce repetitive code. Instead, figure out a way to separate out the responsibilities into separate classes.

FooAccount and FooGroup have the same method A

This tells me that the implementation of method A belongs in its own class (FooA). If it really makes sense for Account and Group to expose method A, then the implementation of FooAccount.A and FooGroup.A should simply be pass-throughs to FooA.A.

Upvotes: 0

Attila
Attila

Reputation: 28772

You should group the methods in the interfaces according to role, not occurrance. So assuming A, B, C belong to one role, D and E belong to another and F is in it own

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

If you have common implementation of methods, you can move them to an abstract base class that provides default implementations

abstract class Helper - S1, S2, S3

then you can declare your concrete classes

class FooAccount extends Helper implements Account

You could also consider using generics if you can extract behavior common to Foo and Bar and have Account be a generic class (taking Foo and Bar) instead of an interface

Upvotes: 2

Related Questions