Re: Factory or Inheritance for Initialisation?



Tim,

Originally the inheritance tree used template method to define the
mechanism that must be used for the classes. It was realised that the
template method wasnt appropriate - there were differences. So we
removed the inheritance/template method, kept a core element to the
original template method in FooBar, and pulled out the differences into
Foo and Bar. As far as FooBar is concerned, Foo and Bar have the same
abstract interface - FooBar doesnt know it is looking at a Foo or a
Bar.

There are two essential elements to the FooBar and Foo/Bar classes.
Some essential looping, invoking and handling return values has been
left to FooBar - this keeps the class clean and tidy. The complicated
inheritance overriding was pulled out into the two strategies. The
issue with this is that when we had the inheritance tree, Foo would
know its methods to override to achieve its role, as well as know the
looping details; same for Bar. As this process happened it was clear
the inheritance tree was wrong - the differences in responsibilities
for Foo and Bar were getting mixed up with the loop details core to
FooBar. The strategies now deal with a concise job, and they dont know
or care that they are part of a loop within FooBar (which they
shouldnt). The actual concept of Foo and Bar has gone, but what
remains is the need to initialise a FooBar with a strategy that
represents what Foo or Bar originally represented.

This is abstract, so I'll try to make this clearer. Foo and Bar have
rules about how to select something from a number of different sets of
data. FooBar, the base-class of the original design, attempted to make
a selection and to process that selection:

public class FooBar {
public FooBar(int maxRetries) {
this.maxRetries = maxRetries;
}

public bool MakeSelection() {
int attempts = 0;
do {
if(SelectNextItem())
return true;
attemts++;
} while(attempts < maxRetries);

return false;
}

protected abstract bool SelectNextItem();

}

public class Foo : FooBar {
public Foo(int retryLimit, other key attributes...)
: base(retryLimit) {
}

protected override bool SelectNextItem() {
// Select an item based on the Foo specific selection algorithm
}
}

public class Bar : FooBar {
public Bar(key attributes...)
: base(UNLIMITED) {
}

protected override bool SelectNextItem() {
// Select an item based on the Bar specific selection algorithm
}
}

What i dont show here is that there were quite a few other abstract
methods in FooBar that caused a problem in that they werent all
relevant and actually made it difficult to understand. So, when a Foo
is asked to SelectNextItem, it only makes a number of attempts to
select something before bombing out. When a Bar attempts the same,
there is no limit on how many times it tries to do this. The actual
selection algorithm is what has been pulled out, favouring composition
for the parts that vary, rather than inheritance.

I dont know if this helps!

k.

.



Relevant Pages