Reputation: 1059
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
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
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