I am implementing a chain of command pattern for a substring search. I can create the chain statically by writing something like this:
matchChain = new CharMatcher( new DotMatcher( new CharMatcher(null)));
where I explicitly declare what each character in the string is going to be to match the pattern Character Period Character ("c.c")
But my goal is to dynamically create this chain for any given key pattern. For example ("\`\`cccc.cc\`\`*c")
would be:
matchChain = new CharMatcher( new CharMatcher( new CharMatcher( new CharMatcher( new CharMatcher(new DotMatcher( new CharMatcher( new CharMatcher( new StarMatcher( new CharMatcher(null)))))));
So the Chain class is an abstract class and each of the matcher classes extend Chain.
So how can I dynamically instantiate a chain based off of the length of the given key/pattern?
CodePudding user response:
Consider a builder method(1):
public class ChainBuilder {
private static final char DOT ='.', STAR = '*';
public static void main(String[] args) {
String pattern = "cccc.cc*c";
Chain chain = chainBuilder(pattern);
//printout chain structure
String space ="", step =" ";
while (true){
if(chain == null){
System.out.println(space chain);
break;
}
System.out.println(space chain.getClass().getSimpleName());
space = step;
chain = chain.getNextLink();
}
}
private static Chain chainBuilder(String pattern){
Chain chain = null;
String reversePattern = new StringBuilder(pattern).reverse().toString();
for(char c : reversePattern.toCharArray()){
switch (c) {
case DOT:
chain = new DotMatcher(chain);
break;
case STAR:
chain = new StarMatcher(chain);
break;
default:
chain = new CharMatcher(chain);
break;
}
}
return chain;
}
}
class Chain {
private final Chain nextLink;
public Chain(Chain nextLink) {
this.nextLink = nextLink;
}
public Chain getNextLink() {
return nextLink;
}
}
class CharMatcher extends Chain{
public CharMatcher(Chain nextLink) {
super(nextLink);
}
}
class DotMatcher extends Chain{
public DotMatcher(Chain nextLink) {
super(nextLink);
}
}
class StarMatcher extends Chain{
public StarMatcher(Chain nextLink) {
super(nextLink);
}
}
(1)
The posted code is an mre. Copy-paste the entire code into ChainBuilder.java
and run.