Java design pattern / transformation pattern - java

I have the below use case where I get events containing JsonString1, I have have to do some processing/transformation to get to Object1 through Object 4. As of now I only have one such case and its likely that in future there there might more such hierarchies (atmost 2-3).
I am unable to decide on what would an elegant way to code this.
JsonString1
|
JsonString2
/ \
JsonString3 JsonString4
| |
Object1 Object2
|
Object3
I could just have an Abstract class for processing JsonStrings 1 to 4 and concrete implementation for each type of the event. Something like
public abstract class AbstractEventProcessor {
public AbstractEventProcessor(String jsonString1) {
// Do processing to get JsonString2, JsonString3 and JsonString4
}
}
public class Event1Processor extends AbstractEventProcessor {
Event1Processor(String str) {
super(str);
}
Object1 getObject1() {
}
Object2 getObject2() {
}
Object3 getObject3() {
}
}
And similar implementations more events as they come along.
Is there a better way to do this ?
Also for now two things are constant, but in a rare case might change.
All events will have JsonString1 .. JsonString4 but the number of Objects at the end will vary. But in future this might change.
Although its very unlikely (but not impossible) that the format of the strings might change (say from json to xml)
Do I accomodate for such changes as well by providing interfaces for string transformations, or it this an overkill ?
Usually I am stuck at such places where I am trying to figure out the most elegant way to do this and end up spending a lot of time ? Is there any general advice as well for this ? :)
Thanks

It's not very clear what you exactly want. However, even without it, when I see your hierarchy, it smells. Usually, during my code reviews, whenever I see too fancy hierarchy like yours, there is something wrong in the design.
Try considering using decorators to avoid the inheritance hell. Thus you may create any combinations you may need in the near and far future. Get some inspiration in the standard java class java.io.Reader and its subclasses.
For your case it would mean something like this (at least how I understand your description):
public interface EventProcessor {
public BaseObject processJsonString(String jsonString);
}
public abstract class AbstractEventProcessor implements EventProcessor {
final private EventProcessor processor;
public AbstractEventProcessor(EventProcessor processor) {
this.processor = processor;
}
}
public class SpecialObject1 extends/implements BaseObject { ... }
public class SpecialObject2 extends/implements BaseObject { ... }
public class SpecialObject3 extends/implements BaseObject { ... }
// Each your future processor will look like this
public class Event1Processor extends AbstractEventProcessor implements EventProcessor {
public Event1Processor(EventProcessor processor) {
super(processor);
}
public SpecialObject1 processJsonString(String jsonString) {
final SpecialObject1 result = (SpecialObject1) super.processJsonString(jsonString);
// here you add this Event processor specific stuff
...
return result;
}
// Maybe more methods here
}
public class Client {
public void useEventProcessor() {
final EventProcessor processor1 = new Event1Processor(new Event2Processor(new Event3Processor(null)));
final SpecialObjectX object1 = processor.processJsonString(jsonString);
final EventProcessor processor2 = new Event51Processor(new Event20Processor(new Event2Processor(null)));
final SpecialObjectY object2 = processor2.processJsonString(jsonString);
}
}

Related

Create Generic class/method to map one object to another

Since I'm a newbie, I would like to know if there is a better way to code this.
Let say we have batch (spring) where we have downloader/processor/mapper/writer for every type of file we receive since we have customized logic for each file type. X number of Mapper , X number of processor for X number of file types.
Currently looking into templatize the code so not much changes may be required when new type is introduced. Below is my idea. so let say mapper, we have different objects for different file types and all of them will be converted to object of Class CustomObject as below. mapper bean in sample spring context
bean id = "file1Mapper" class = "com.filemapper.file1Mapper"
and it invokes file1Mapper class which has mapping logic. Same for other files.
This is what I'm coming up with to avoid all those file1mapper, file2mapper...... instead one generic mapper which does all together, but looking for better solutions,
public class GMapper{
public <T> CustomObject map(T item){
CustomObject customObject = new CustomObject()
.WithABCDetails(getABCDetails(item));
}
private <T> XYZDetails getABCDetails(T item) {
ABCDetails details = new ABCDetails();
if( item instanceof A){
A a = (A)item;
// read a and map it to ABCDetails object
}
if( item instanceof B){
B b = (B)item;
// read b and map it to ABCDetails object
}
...
...
// repeat this if loop for mapping all file types.
return details;
}
}
Sample jsons
class ABCDetails{
// JsonProperty
Object1 ob1;
Object2 ob2;
Integer d;
}
class Object1{
// JsonProperty
Object3 ob3;
String abc;
String def;
}
class Object2{
// JsonProperty
String ab;
Integer e;
}
class A{
// JsonProperty
String e;
String d; // ex, this is mapped to Object 2 String "ab"
}
This does't look so professional and I believe there might be better ways to do it. Can someone please share an example or explanation on how can this code be made better. I also reading Functional interface to see if that could help.
Thanks in advance.
It is impossible to understand what you need. So I will give some common advice.
Format your code - use tabs/spaces to indent.
Do not put capital letters together - replace ABCDetails with AbcDetails. No one cares how real world name looks like.
Do not write meaningless comments - say no to // JsonProperty
Name variables so that someone can understand what they are supposed to store - avoid {Object1 ob1; Object2 ob2; Integer d;}
Do not write if ... else if ... else if ... or case when ... since this scales badly. Use Map. Examples below.
And a general solution to your problem: use plugin architecture - the best thing (and maybe the only thing) that OOP can offer. Just make all your processors implement common interface. And to work with plugins use dispatcher pattern.
First create all processors.
public interface FileProcessor {
String extension();
void process(String filename);
}
#Component
public final class CsvFileProcessor implements FileProcessor {
public String extension() {
return "csv";
}
public void process(String filename) {
/* do what you need with csv */
}
}
#Component
public final class JsonFileProcessor implements FileProcessor {
public String extension() {
return "json";
}
public void process(String filename) {
/* do what you need with json */
}
}
Then inject them into your dispatcher. Do not forget to process errors, for example, some files may not have suffix, for some files you will not have processor, etc.
#Component
public final class FileDispatcher {
private final Map<String, FileProcessor> processorByExtension;
#Autowired
public FileDispatcher(List<FileProcessor> processors) {
processorByExtension = processors.stream().collect(Collectors.toMap(p -> p.extension(), p -> p));
}
public void dispatch(String filename) {
String extension = filename.split("//.")[1];
processorByExtension.get(extension).process(filename);
}
}
Now if you need to support new file format you have to add only one class - implementation of FileProcessor. You do not have to change any of already created classes.

Using enum to implement multitons in Java

I would like to have a limited fixed catalogue of instances of a certain complex interface. The standard multiton pattern has some nice features such as lazy instantiation. However it relies on a key such as a String which seems quite error prone and fragile.
I'd like a pattern that uses enum. They have lots of great features and are robust. I've tried to find a standard design pattern for this but have drawn a blank. So I've come up with my own but I'm not terribly happy with it.
The pattern I'm using is as follows (the interface is highly simplified here to make it readable):
interface Complex {
void method();
}
enum ComplexItem implements Complex {
ITEM1 {
protected Complex makeInstance() { return new Complex() { ... }
},
ITEM2 {
protected Complex makeInstance() { return new Complex() { ... }
};
private Complex instance = null;
private Complex getInstance() {
if (instance == null) {
instance = makeInstance();
}
return instance;
}
protected void makeInstance() {
}
void method {
getInstance().method();
}
}
This pattern has some very nice features to it:
the enum implements the interface which makes its usage pretty natural: ComplexItem.ITEM1.method();
Lazy instantiation: if the construction is costly (my use case involves reading files), it only occurs if it's required.
Having said that it seems horribly complex and 'hacky' for such a simple requirement and overrides enum methods in a way which I'm not sure the language designers intended.
It also has another significant disadvantage. In my use case I'd like the interface to extend Comparable. Unfortunately this then clashes with the enum implementation of Comparable and makes the code uncompilable.
One alternative I considered was having a standard enum and then a separate class that maps the enum to an implementation of the interface (using the standard multiton pattern). That works but the enum no longer implements the interface which seems to me to not be a natural reflection of the intention. It also separates the implementation of the interface from the enum items which seems to be poor encapsulation.
Another alternative is to have the enum constructor implement the interface (i.e. in the pattern above remove the need for the 'makeInstance' method). While this works it removes the advantage of only running the constructors if required). It also doesn't resolve the issue with extending Comparable.
So my question is: can anyone think of a more elegant way to do this?
In response to comments I'll tried to specify the specific problem I'm trying to solve first generically and then through an example.
There are a fixed set of objects that implement a given interface
The objects are stateless: they are used to encapsulate behaviour only
Only a subset of the objects will be used each time the code is executed (depending on user input)
Creating these objects is expensive: it should only be done once and only if required
The objects share a lot behaviour
This could be implemented with separate singleton classes for each object using separate classes or superclasses for shared behaviour. This seems unnecessarily complex.
Now an example. A system calculates several different taxes in a set of regions each of which has their own algorithm for calculting the taxes. The set of regions is expected to never change but the regional algorithms will change regularly. The specific regional rates must be loaded at run time via remote service which is slow and expensive. Each time the system is invoked it will be given a different set of regions to calculate so it should only load the rates of the regions requested.
So:
interface TaxCalculation {
float calculateSalesTax(SaleData data);
float calculateLandTax(LandData data);
....
}
enum TaxRegion implements TaxCalculation {
NORTH, NORTH_EAST, SOUTH, EAST, WEST, CENTRAL .... ;
private loadRegionalDataFromRemoteServer() { .... }
}
Recommended background reading: Mixing-in an Enum
Seems fine. I would make initialization threadsafe like this:
enum ComplexItem implements Complex {
ITEM1 {
protected Complex makeInstance() {
return new Complex() { public void method() { }};
}
},
ITEM2 {
protected Complex makeInstance() {
return new Complex() { public void method() { }}
};
private volatile Complex instance;
private Complex getInstance() {
if (instance == null) {
createInstance();
}
return instance;
}
protected abstract Complex makeInstance();
protected synchronized void createInstance() {
if (instance == null) {
instance = makeInstance();
}
}
public void method() {
getInstance().method();
}
}
The modifier synchronized only appears on the createInstance() method, but wraps the call to makeInstance() - conveying threadsafety without putting a bottleneck on calls to getInstance() and without the programmer having to remember to add synchronized to each to makeInstance() implementation.
This works for me - it's thread-safe and generic. The enum must implement the Creator interface but that is easy - as demonstrated by the sample usage at the end.
This solution breaks the binding you have imposed where it is the enum that is the stored object. Here I only use the enum as a factory to create the object - in this way I can store any type of object and even have each enum create a different type of object (which was my aim).
This uses a common mechanism for thread-safety and lazy instantiation using ConcurrentMap of FutureTask.
There is a small overhead of holding on to the FutureTask for the lifetime of the program but that could be improved with a little tweaking.
/**
* A Multiton where the keys are an enum and each key can create its own value.
*
* The create method of the key enum is guaranteed to only be called once.
*
* Probably worth making your Multiton static to avoid duplication.
*
* #param <K> - The enum that is the key in the map and also does the creation.
*/
public class Multiton<K extends Enum<K> & Multiton.Creator> {
// The map to the future.
private final ConcurrentMap<K, Future<Object>> multitons = new ConcurrentHashMap<K, Future<Object>>();
// The enums must create
public interface Creator {
public abstract Object create();
}
// The getter.
public <V> V get(final K key, Class<V> type) {
// Has it run yet?
Future<Object> f = multitons.get(key);
if (f == null) {
// No! Make the task that runs it.
FutureTask<Object> ft = new FutureTask<Object>(
new Callable() {
public Object call() throws Exception {
// Only do the create when called to do so.
return key.create();
}
});
// Only put if not there.
f = multitons.putIfAbsent(key, ft);
if (f == null) {
// We replaced null so we successfully put. We were first!
f = ft;
// Initiate the task.
ft.run();
}
}
try {
/**
* If code gets here and hangs due to f.status = 0 (FutureTask.NEW)
* then you are trying to get from your Multiton in your creator.
*
* Cannot check for that without unnecessarily complex code.
*
* Perhaps could use get with timeout.
*/
// Cast here to force the right type.
return type.cast(f.get());
} catch (Exception ex) {
// Hide exceptions without discarding them.
throw new RuntimeException(ex);
}
}
enum E implements Creator {
A {
public String create() {
return "Face";
}
},
B {
public Integer create() {
return 0xFace;
}
},
C {
public Void create() {
return null;
}
};
}
public static void main(String args[]) {
try {
Multiton<E> m = new Multiton<E>();
String face1 = m.get(E.A, String.class);
Integer face2 = m.get(E.B, Integer.class);
System.out.println("Face1: " + face1 + " Face2: " + Integer.toHexString(face2));
} catch (Throwable t) {
t.printStackTrace(System.err);
}
}
}
In Java 8 it is even easier:
public class Multiton<K extends Enum<K> & Multiton.Creator> {
private final ConcurrentMap<K, Object> multitons = new ConcurrentHashMap<>();
// The enums must create
public interface Creator {
public abstract Object create();
}
// The getter.
public <V> V get(final K key, Class<V> type) {
return type.cast(multitons.computeIfAbsent(key, k -> k.create()));
}
}
One thought about this pattern: the lazy instantiation isn't thread safe. This may or may not be okay, it depends on how you want to use it, but it's worth knowing. (Considering that enum initialisation in itself is thread-safe.)
Other than that, I can't see a simpler solution that guarantees full instance control, is intuitive and uses lazy instantiation.
I don't think it's an abuse of enum methods either, it doesn't differ by much from what Josh Bloch's Effective Java recommends for coding different strategies into enums.

How to test the interaction between a method and its two helpers?

I have the following structure of my Java code:
public MyClass {
// some class variables
...
private void process() {
private MyObject obj;
...
obj = createHelper();
...
messageHelper(obj, "One of several possible strings");
...
messageHelper(obj, "Another call with a different string");
...
}
private MyObject createHelper {
MyObject obj = new MyObject();
// some Setter calls
...
return obj;
}
private void messageHelper (MyOject obj, String message) {
...
}
}
I would like to test, that based on properties obj (that I would like to specify), messageHelper() receives the right string. In other words I need to control the result of one method and have access to the parameters of the other.
I'm still very shaky with all this Mock/Stub/Spy stuff.
It seems to me that I need to Spy on MyClass, stub CreateHelper() with a "manually" created object and not sure what for intercepting call parameters for messageHelper().
Also I noted that Wiki cautions against using Spies:
Think twice before using this feature. It might be better to change
the design of the code under specification.
So what would an appropriate Spocky way to accomplish the task?
Slightly Refactored Code: (5/5/14)
public MyClass {
// some class variables
private messageSevice = new messageService();
...
private void process() {
private MyObject obj;
...
obj = new MyObject(parameters ...);
...
if (someCondition) {
messageService.produceMessageOne(obj);
}
...
if (otherCondition) {
messageService.produceMessageTwo(obj);
{
...
}
}
public class MessageService implements IMessageService {
private final static MSG_ONE = "...";
private final static MSG_TWO = "...";
...
public void produceMessageOne(MyObject obj) {
produceMessage(obj, MSG_ONE);
...
}
public void produceMessageOne(MyObject obj) {
produceMessage(obj, MSG_TWO);
}
private void produceMessage(MyObject obj, String message) {
...
}
}
I would greatly appreciate if someone suggests the way it should be tested with Spock.
The caution you're referring to is rightfully there. There's a very good correlation between testable code and good design (I recommend watching this lecture from Michael Feathers to understand why http://www.youtube.com/watch?v=4cVZvoFGJTU).
Using spies tends to be a heads up for design issues since it usually arises from the impossibility of using regular mocks and stubs.
It's a little hard to predict from your example, since you're obviously using pseudo names, but it seems that the design of the MyClass class violates the single responsibility principle (http://en.wikipedia.org/wiki/Single_responsibility_principle), since it does processing, creation and messaging (3 responsibilities).
If you're willing to change your design, so that the processing class (MyClass) will do only processing, you'll be providing another class that does the creation (MyObjectFactory), and yet another class that does the messaging (MyObjectMessager) either through a constructor, setter methods or by dependency injection.
Using this new design, you can create an instance of the class you're testing (MyClass), and pass it mock objects of both the factory and messaging classes. Then you'll be able to verify whatever you want on both.
Take a look at this example (using Mockito):
public class MyClassTest {
#Test
public void testThatProcessingMessagesCorrectly() {
MyObject object = mock(MyObject.class);
MyObjectFactory factory = mock(MyObjectFactory.class);
when(factory.createMyObject()).thenReturn(object);
MyObjectMessager messager = mock(MyObjectMessager.class);
MyClass processor = new MyClass(factory, messager);
processor.process();
verify(factory).createMyObject();
verify(messager).message(EXPECTED_MESSAGE_1);
verify(messager).message(EXPECTED_MESSAGE_2);
...
verify(messager).message(EXPECTED_MESSAGE_N);
}
...
}
Here's a Spock example (untested, double check before using ...):
public class MyClassSpec extends Specification {
def "check that the right messages are produced with the expected object"() {
given:
def messageService = Mock(IMessageService)
def testedInstance = new MyClass()
testedInstance.setMessageService(messageService)
when:
testedInstance.process()
then:
1 * messageService.produceMessageOne(_)
1 * messageService.produceMessageTwo(_)
}
}
If you're a hammer, every problem is a nail
I'd like to call exception-to-the-rule here and say that sometimes stubbing private methods - necessitating spies - can be both correct and useful.
#eitanfar is most likely accurate in his analysis of the function, and 95% of the time this is the case, but as with most things - I believe - not always.
This is for those of us who believe they have an exception but get the usual "code smell" argument.
My example is a complex argument validator. Consider the following:
class Foo {
def doThing(...args) {
doThing_complexValidateArgs(args)
// do things with args
}
def private doThing_complexValidateArgs(...args) {
// ... * 20 lines of non-logic-related code that throws exceptions
}
}
Placing the validator in it's own class IMO seperates the concern too much. (a FooMethodArgumentValidator class?)
Refactoring out the validation arguably significantly improves readability of the doThing() function.
doThing_complexValidateArgs() should not be public
The doThing() function benefits from the reability of a simple call validateArgs(...) and maintains encapsulation.
All I need to be sure of now is that I have called the function within the parent one. how can I do that? well - correct me if I'm wrong - but in order to do that, I need a Spy().
class FooSpec extends Specification {
class Foo {
def doThing(...args) {
doThing_controlTest(args)
doThing_complexValidateArgs(*args)
// do things with args
}
def doThing_controlTest(args) {
// this is a test
}
def private doThing_complexValidateArgs(...args) {
// ... * 20 lines of code
}
}
void "doThing should call doThing_complexValidateArgs" () {
def fooSpy = Spy(Foo)
when:
fooSpy.doThing(1, 2, 3)
then:
1 * fooSpy.doThing_controlTest([1,2,3]) // to prove to ya'll we got into the right method
1 * fooSpy.invokeMethod('doThing_complexValidateArgs', [1, 2, 3]) // probably due to groovy weirdness, this is how we test this call
}
}
Here is my real life example I used for a static private method:
#SuppressWarnings("GroovyAccessibility")
#ConfineMetaClassChanges(DateService) // stops a global GroovySpy from affecting other tests by reseting the metaclass once done.
void "isOverlapping calls validateAndNormaliseDateList() for both args" () {
List list1 = [new Date(1L), new Date(2L)]
List list2 = [new Date(2L), new Date(3L)]
GroovySpy(DateService, global: true) // GroovySpy allows for global replacement. see `org.spockframework.mock.IMockConfiguration#isGlobal()`
when:
DateService.isOverlapping(list1, list2)
then:
1 * DateService.isOverlapping_validateAndNormaliseDateList('first', list1) // groovy 2.x currently allows private method calls
1 * DateService.isOverlapping_validateAndNormaliseDateList('second', list2)
}

Trouble implementing strategy and composite pattern to give varying behaviour in a game

I'm running into real trouble trying to complete a practical that requires using strategy and composite pattern. I am trying to create a collection of vehicles which can have different behavior depending on the surface they are on. However, these vehicles can have more than one behaviour on a surface - for example, they could have snow drive and rain drive at the same time, if the weather conditions are set to snow and rain.
I have a class called AbstractVehicle, which has two concrete subclasses, Car and Boat.
I then have an interface called IBehaviour. Implementing this interface is two abstract classes called LandBehaviour and WaterBehaviour (which are the top tier of the composite pattern). Each of these have a collection of subclasses. Focussing solely on LandBehaviour, its subclasses are SnowBehaviour, StandardBehaviour and a few others including LandAssembly.
The idea was that I would put the code for the upper-tier of composite in LandBehaviour. Then, each of the concrete subclasses would have empty implementations of the add, remove and list parts of composite, with the LandAssembly class containing the code needed to actually combine various behaviours together.
This is intended to produce the result that, for example, a car could have both StandardBehaviour and SnowBehaviour at the same time.
Rather than posting large amounts of code (and there is a lot of it), I was hoping for some feedback on the basic structure I am trying to implement. I am getting a few errors right now such as null pointer exceptions and rather than spent a long time trying to fix them, I wanted to get an idea on whether the layout of the project was right to begin with.
Edit: Adding code - which generates a null pointer exception
This is my AbstractVehicle class:
public AbstractVehicle (IBehaviour behaviourIn) {
behaviour = behaviourIn;
}
public void setBehaviour(IBehaviour ib) {
behaviour = ib;
}
public IBehaviour getBehaviour() {
return behaviour;
}
public void move() {
behaviour.ensureCorrectBehaviour();
}
The car subclass:
public Car () {
super(new StandardBehaviour());
}
The IBehaviour interface:
public interface IBehaviour {
public void ensureCorrectBehaviour();
}
The LandBehaviour abstract class:
public void ensureCorrectBehaviour() {
}
public ILandBehaviour () {
}
private ILandBehaviour landBehaviour;
public ILandBehaviour (ILandBehaviour landBehaviour) {
this.landBehaviour = landBehaviour;
}
public ILandBehaviour getBehaviour() {
return landBehaviour;
}
public abstract void addBehaviour(ILandBehaviour behaviour);
public abstract void removeBehaviour(ILandBehaviour behaviour);
public abstract ILandBehaviour[] getBehaviours();
An example of a concrete behaviour subclass (RacingBehaviour):
public RacingBehaviour(ILandBehaviour landBehaviour) {
super(landBehaviour);
}
public RacingBehaviour() {}
#Override
public void ensureCorrectBehaviour() {
System.out.println("Vehicle is racing.");
}
public void addBehaviour(ILandBehaviour behaviour) {}
public void removeBehaviour(ILandBehaviour behaviour) {}
public ILandBehaviour[] getBehaviours() {
return null;
}
And finally the LandAssembly class:
public class LandAssembly extends ILandBehaviour {
private List<ILandBehaviour> behaviours;
public LandAssembly(ILandBehaviour landBehaviour) {
super(landBehaviour);
behaviours = new ArrayList<ILandBehaviour>();
}
public LandAssembly() {}
public void addBehaviour(ILandBehaviour behaviour) {
behaviours.add(behaviour);
}
public void removeBehaviour(ILandBehaviour behaviour) {
behaviours.remove(behaviour);
}
public ILandBehaviour[] getBehaviours() {
return behaviours.toArray(new ILandBehaviour[behaviours.size()]);
}
}
I am using this runner:
AbstractVehicle aCar = new Car(120);
aCar.move();
ILandBehaviour snow = new SnowBehaviour();
ILandBehaviour racing = new RacingBehaviour();
ILandBehaviour as = new LandAssembly();
as.addBehaviour(snow);
as.addBehaviour(racing);
Before I implemented the composite, everything was fine. I was able to use the client to create a new car, call its move() method, then change its behaviour, call move() again and see the difference. I'm aware however that I'm now kinda leaving the ensureCorrectBehaviour() method in my implementation of the composite pattern, which is obviously wrong. I'm also aware that after doing this, the "new" part of the Car constructor didn't work - I had to add an empty constructor each behaviour.
I can see glaring problems in the code I've created, I just don't quite see how to fix them.
If you are concerned about the design patterns, a class diagram would be extremely useful. You have many features, and you group those features into higher levels of abstractions (such as snow/land/water/etc.) But your vehicle only takes in one behavior. Does a vehicle need to be able to have multiple features? (Surely it does as you mention).
You might consider having concretely-defined strategies in your class, where each implementation of the strategy can vary.
public abstract class Bird
{
protected BirdCallStrategy callStrat;
protected FlyStrategy flyStrat;
}
public class Duck
{
public Duck()
{
callStrat = new QuackStrategy();
flyStrategy = new FlySouthForWinterStrategy(TimeOfYear);
}
}
public class Chicken
{
public Chicken()
{
callStrat = new CluckStrategy();
flyStrat = new NoFlyStrategy();
}
}
This works well if you have distinct abstractions for your strategies. In this case Flying and BirdCalling have nothing to do with each other, but they are allowed to vary by implementation at runtime (Quacking, chirping or flying, not flying, etc.)
If however, you want to create varying instances on the fly without subtyping, you might want to look into the Decorator pattern. The decorator pattern allows you to apply any combination of "features" to an instance at run-time.
So you might end up with an object that is instantiated such as:
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator(new SimpleWindow()));

What is the Best Way to Extend Functionality?

I've run into a situation in which I was to extend the functionality of a given class, but I'm not sure of the best way to go about this. I started by invoking functionality "upwards" and have now switched to "downwards", but I see issues with both. Let me explain what I mean. First, the "upwards" approach:
public class ParentValidator
{
public void validate() {
// Some code
}
}
public class ChildValidator extends ParentValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void validate() {
super.validate();
// Some code
}
}
This functions perfectly well, but it requires that I always remember to place super.validate() in my method body or the logic in the parent class(es) won't be executed. In addition, extension in this manner can be considered "unsafe" due to the fact that a child class could actually replace/modify the code defined in the parent class. This is what I call invoking methods "upwards" because I'm invoking methods from higher level classes as I go.
To counter these shortfalls, I decided to make ParentValidator.validate() final and have it invoke a different method. Here's what my code was modified to:
public class ParentValidator
{
public final void validate() {
// Some code
subValidate();
}
protected void subValidate() {}
}
public class ChildValidator extends ParentValidator
{
#Override
public final void subValidate() {
// Some code
subSubValidate();
}
protected void subSubValidate() {}
}
public class GrandchildValidator extends ChildValidator
{
#Override
public void subSubBalidate() {
// Some code
subSubSubValidate();
}
protected void subSubSubValidate();
}
This is what I was referring to when I say that I'm calling downwards as each class invokes methods on classes "down" the inheritance chain.
Using this approach, I can be guaranteed that the logic in the parent class(es) will be executed, which I like. However, it doesn't scale well. The more layers of inheritance I have, the uglier it gets. At one level, I think this is very elegant. At two levels, it starts to look shoddy. At three or more, it's hideous.
In addition, just as I had to remember to invoke super.validate() as the first line of any of my children's validate methods, I now have to remember to invoke some "subValidate" method at the end of any of my parent's validate methods, so that didn't seem to get any better.
Is there a better way to do this type of extension that I haven't even touched on. Either of these approaches have some serious flaws and I'm wondering if there's a better design pattern I could be using.
In what you describe as your first approach you are using simple inheritance, your second approach is closer to what the Gang of Four [GoF] called a Template Method Pattern because your parent class is using the so-called Hollywood Principle: "don't call us, we'll call you".
However, you could benefit from declaring the subvalidate() method as abstract in the parent class, and by this, make sure all subclasses are forced to implement it. Then it would be a true template method.
public abstract class ParentValidator
{
public final void validate() {
//some code
subValidate();
}
protected abstract void subValidate() {}
}
Depending on what you are doing there are other patterns that could help you do this in a different manner. For instance, you could use a Strategy Pattern to peform the validations, and by this favoring composition over inheritance, as suggested before, but a consequence is that you will need more validation classes.
public abstract class ParentValidator
{
private final ValidatorStrategy validator;
protected ParentValidator(ValidatorStrategy validator){
this.validator = validator;
}
public final void validate() {
//some code
this.validator.validate();
}
}
Then you can provide specific validation strategies for every type of Validator that you have.
If you want to get the best of both worlds you might considering implementing the solution as a Decorator Pattern where subclasses can extend the functionality of a parent class and still stick to a common interface.
public abstract class ValidatorDecorator implements Validator
{
private final Validator validator;
protected ParentValidator(Validator validator){
this.validator = validator;
}
public final void validate() {
//some code
super.validate(); //still forced to invoke super
this.validator.validate();
}
}
All patterns have consequences and advantages and disadvantages that you must consider carefully.
I'd prefer to 1) program against interfaces, and 2) opt for composition over inheritance. This is how I have done. Some people like it, some do not. It works.
// java pseudocode below, you'll need to work the wrinkles out
/**
* Defines a rule or set of rules under which a instance of T
* is deemed valid or invalid
**/
public interface ValidationRule<T>
{
/**
* #return String describing invalidation condition, or null
* (indicating then that parameter t is valid */
**/
String apply(final T t);
}
/**
* Utility class for enforcing a logical conjunction
* of zero or more validatoin rules on an object.
**/
public final class ValidatorEvaluator
{
/**
* evaluates zero or more validation rules (as a logical
* 'AND') on an instance of type T.
**/
static <T> String apply(final T t, ValidationRule<T> ... rules)
{
for(final ValidationRules<T> v : rules)
{
String msg = v.apply(t);
if( msg != null )
{
return msg; // t is not valid
}
}
return null;
}
}
// arbitrary dummy class that we will test for
// i being a positive number greater than zero
public class MyFoo
{
int i;
public MyFoo(int n){ i = n; }
///
}
public class NonZeroValidatorRule implements ValidatorRule<MyFoo>
{
public String apply(final MyFoo foo)
{
return foo.i == 0 ? "foo.i is zero!" : null;
}
}
// test for being positive using NonZeroValidatorRule and an anonymous
// validator that tests for negatives
String msg = ValidatorEvaluator.apply( new MyFoo(1),
new NonZeroValidatorRule(),
new ValidatorRule<MyFoo>()
{
public String apply(final MyFoo foo)
{
return foo.i < 0 ? "foo.i is negative!" : null;
}
}
);
if( msg == null )
{
\\ yay!
...
}
else
{
\\ nay...
someLogThingie.log("error: myFoo now workie. reason=" + msg );
}
More complex, non-trivial evaluation rules can be implemented this way.
The key here is that you should not use inheritance unless there exists a is-a relationship. Do not use it just to recycle or encapsulate logic. If you still feel you need to use inheritance, then don't go overkill trying to make sure that every subclass executes the validation logic inherited from the superclass. Have implementations of each subclass do an explicit execution on super:
public class ParentValidator
{
public void validate() { // notice that I removed the final you originally had
// Some code
}
}
pubic class ChildValidator extends ParentValidator
{
#Override
public void validate() {
// Some code
super.validate(); // explicit call to inherited validate
// more validation code
}
}
Keep things simple, and don't try to make it impossible or fool-proof. There is a difference between coding defensively (a good practice) and coding against stupid (a futile effort.) Simply lay out coding rules on how to subclass your validators. That is, put the onus on the implementors. If they cannot follow the guidelines, no amount of defensive coding will protect your system against their stupidity. Ergo, keep things clear and simple.
I prefer to using composition over inheritance if your subSubSubValidate is related general functionality. You can extract new class and move it there than you can use it without inheritance in the other classes.
There is also
"Favor 'object composition' over
'class inheritance'." (Gang of Four
1995:20)
maybe a look at the visitor pattern may help you to develop your pattern.
Here are some information on it : http://en.wikipedia.org/wiki/Visitor_pattern

Categories

Resources