Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Class Normalization using Abstract Classes

 
Pho Tek
Ranch Hand
Posts: 782
Chrome Python Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Class Normalization talks about refactoring common data + behaviour into superclasses/superinterfaces.

Currently I am using an Abstract class to purely contain common data fields while subclasses will extend the Abstract class and add additional fields on their own. Is this a good move ?

Everyone knows that Abstract classes cannot be instantiated; but I currently have a non-abstract constructor that will take the inputs for the common data elements. This seems a bit strange but it compiles fine. The constructor of my subclasses will then do a



Any comments on this design ?

Regards

Pho
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's exactly how the experts do it.

Note that having a constructor is a requirement of being a class. If you don't define a constructor for a class -- abstract or not -- the compiler will generate a public no-argument empty constructor for you. But having a constructor doesn't mean the class itself can be instantiated.

As well, all constructors up the chain of superclasses are executed no matter what. You cannot skip calling the superclass's constructor. Thus, since abstract classes must be extended to be used, and their subclasses must call the superclass's constructor, abstract classes must have a constructor.
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I currently have a non-abstract constructor...

In Java, there is no such thing as an abstract constructor, even if you wanted to have one. As David points out, even abstract classes need a way to initialize any data, so a constructor like this is very appropriate.

Layne
 
Pho Tek
Ranch Hand
Posts: 782
Chrome Python Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Therefore, there isn't much difference between an abstract class and a non-abstract class other than the fact the former cannot be instantiated. Of course, there wouldn't be much utility in abstract classes if you don't have any abstract methods.

I've been reading DDD by Eric Evans and he seems to frown upon my design above. In the chapter on Factories, he writes:

Avoid calling constructors within constructors of other classes. Constructors should be dead simple. Complex assemblies, call for FACTORIES.

I wonder if my aforementioned design fall into this category of constructors with "complex assemblies".

Pho
 
David Harkness
Ranch Hand
Posts: 1646
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Pho Tek:
I wonder if my aforementioned design fall into this category of constructors with "complex assemblies".
Domain-Driven Design is a very good book, and I agree with the general advice here.

The key to that quote is "constructors of other classes." As I said, you cannot avoid calling the superclass's constructor from the subclass's constructor. Well, you can actually, by calling a different constructor of the subclass which will then call a superclass constructor.

One goal of the Factory pattern is to have the Factory create classes and wire them together. This is unrelated to the discussion regarding abstract classes, though it is a worthy discussion.

An example would be a business object that requires two DAOs to do its work. The business object should not instantiate the two DAOs. Rather a BO Factory (or a framework like Spring) should instantiate the objects individually and set references between them appropriately. The following code is extremely trivial just to show how this applies.Of course, as with any design pattern you want to make sure you don't go off the deep end. If you have a class that uses an internal HashMap to fulfill its contract, you don't need a separate Factory to build that class and hand it a HashMap; that's going too far.
 
Stan James
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Excellent thread! You're probably doing just fine, but your very first idea - refactoring common code into a superclass - is not a blanket solution. Two classes with common code don't necessarily belong in an inheritance tree together. Someone here at work refactored all database processing in a smallish system into a root superclass. This gives a false "is-a" tree and prevents lower classes from extending something else more useful. The other choice is composition: everything that does database processing uses a common mechanism class. Much more flexible and reusable in the long run.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic