[plt-scheme] Abstracting Visitors (is in Java)
Below is a class that houses some file filters. At the moment there are 2
filters defined - one to match on file sizes, the other is a file name
pattern matcher.
I have achieved one level of abstraction by hoisting the filter code to the
abstract class and passing the required filter as a "lambda" function.
However there is more that could be abstracted. Both forCons methods start
with
return first instanceof Cons ?
new Cons(((Cons)first).accept(this), ((AList)rest.accept(this))):
to deal with the case of nested lists.
I thought of hoisting that test into an abstract forCons class and then
calling it via a super method in which case it would become
if ( first instanceof Cons)
return new Cons(((Cons)first).accept(this),
((AList)rest.accept(this)));
but what would I return if the If statement failed?
Perhaps there is a structural fault with my design.
abstract class Filter {
//This class house classes that run filters on the list of files
// So far we have a file size filter and a pattern match filter
//
//Constructors
Filter() {}
public Object forEmpty(){
return Empty.ONLY;
}
//The code for both filters has been abstracted as it is identical save
for
// the filter condition.
//The filter condition is defined as an anonymous function (implementing
class lambda)
// and passed in as a parameter.
//It was also necessary to pass in the visitor as a parameter so that the
abtracted
// routine would know where it had been called from
private static Object filter(Object first, AList rest, IList visitor,
ILambda op) {
final AList getTheRest = ((AList)rest.accept(visitor));
return ((Boolean)op.execute()).booleanValue() ?
new Cons(first, getTheRest) :
getTheRest;
}
static class PatternMatchV extends Filter implements IList {
AList pattern;
PatternMatchV(AList pattern) {
this.pattern = pattern;
}
//________________________________________________________________________
public Object forCons(final Object first, final AList rest) {
return first instanceof Cons ?
new Cons(((Cons)first).accept(this), ((AList)rest.accept(this))):
//Pattern Matching Filter
filter(first, rest, this, new ILambda() {
public Object execute() {
return new PatternMatch(pattern.toString(),
((MyFile)first).name).match();
}
});
}
}
static class SizeV extends Filter implements IList {
long fileSize;
SizeV(long fileSize) {
this.fileSize = fileSize;
}
//__________________________________________________________________________
public Object forCons(final Object first, final AList rest) {
return first instanceof Cons?
new Cons(((Cons)first).accept(this), ((AList)rest.accept(this))):
//File size filter
filter(first, rest, this, new ILambda() {
public Object execute() {
return ((MyFile)first).size > fileSize;
}
});
}
}
}
_________________________________________________________________
Windows Live Messenger has arrived. Click here to download it for free!
http://imagine-msn.com/messenger/launch80/?locale=en-gb