Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Abstract Class or Static Utility Class Design Choice

I am implementing a few strategies (Strategy Pattern) which have some common behavior and am undecided where the common operations should live.

  • Assuming I 1 context and 3 strategies, some of the operations used in the strategies are shared, some are needed only by 2 others just be 1 of the strategies.
  • There is no member level state shared, therefore the only operations are effectively stateless.
  • The intention of the operations are to support the formatting of state to a file, like a view helper.

Option 1: Make an AbstractStrategy class

  • I'm using Java so this immediately takes away using this feature in the future.
  • Inheritance tends to result. in a ridge structure.
  • Operations would be final.

Option 2: Create a Util class of static helpers

  • Flexible, but feels like a code smell for some reason.
  • Not ridged.

Any recommendations or preferences?

Note the level I am working at is the Strategy level, not the Context level (see wikipedia link).

like image 607
JARC Avatar asked Jul 26 '10 15:07

JARC


2 Answers

There is one reason... one huge reason... to use a static Util class over an abstract class or interface.

So you can add more methods at a later date.

With an abstract class or interface, any change you make to that class/interface has to be changed in all classes that inherit from it. This is especially problematic if you're writing a public API.

The Java framework has util classes with static methods scattered throughout. The most well known ones are in the java.util package: Collections and Arrays.

like image 171
Powerlord Avatar answered Oct 08 '22 22:10

Powerlord


There are many ways to achieve this.

  1. Use an abstract class and make the variable parts of the execution into abstract methods => Some strategies would implement all operations (by overriding the abstract methods) while others could skip the optional ones. Note that in this case the optional operations could be empty hook methods rather than abstract methods. That way you avoid the hassle of having to implement these operations as empty methods in the subclass.

  2. Use an actual 'Strategy' interface (with an execute method like in the wikipedia article you pointed to). The client class would then be provided by an implementation of the strategy (could be an anonymous inner class or an actual full blown strategy class).

The first is more straightforward but more rigid: if you have to modify the number of operations (specially the abstract ones), all the subclasses have to be updated.

The second is more flexible but you'll have to find a way to "share" common operations between different strategies either by delegating or using static utility methods.

like image 20
dimdm Avatar answered Oct 08 '22 23:10

dimdm