我不确定是否有一个涵盖这个问题的模式,但是这里有。在编写调用分析算法(例如解析器或计算实现)的方法时,有相当多的代码来读取源,应用算法,然后将结果转换为有用的东西。基本上是20-30行代码和一个经常变化的算法/解析器/标记器。
所以....到目前为止我看到的选项是:
是否有一个巧妙的技巧或一般方法构造编程模式来解决这个问题?
提前致谢。
- 编辑 -
要删除这个问题的一些抽象,这里是我所谈论的原型。所以真的只有tokenizer的实现发生了变化。
pubic void tokenizeData(Filename datablob){
// convert filename
// open file
// handle file errors
// other code
// assign desired tokenizer
tokenizer = new TokenizerImplementation (or some other variation);
tokenizedData = tokenizer( cleansedData );
// parsing and collection code
// more error processing code
// cleanup code
}
答案 0 :(得分:1)
我还会根据@Lucas Oliveira的建议,对Interface
和Abstract
+ Template Method
的某些组合进行个人访问,但是对于选择适当的Tokenizer实现的问题,您可能还需要 Factory
(模式)来动态加载另一个Tokenizer impl。基于工厂上下文或参数而不更改模板方法tokenizeData()
的内容。
示例1经典参数化工厂:
public class TokenizerFactory
{
private static final Logger logger = LoggerFactory.getLogger(TokenizerFactory.class);
private final int version;
public TokenizerFactory(int version) {
this.version = version;
}
public ITokenizer getInstance() {
switch(version) {
case 1: return new TokenizerV1();
case 2: return new TokenizerV2();
default: return new DefaultTokenizer();
}
}
}
示例2动态类加载静态工厂(原谅我的名字):
public class TokenizerFactory
{
private static final Logger logger = LoggerFactory.getLogger(TokenizerFactory.class);
private TokenizerFactory() {}
// Here eg. ETokenizerType is a enum storing class associated to the type.
public static ITokenizer getInstance(ETokenizerType dtype) {
try {
return (ITokenizer)dtype.getClassVar().newInstance();
}
catch(Throwable ex) {
logger.error("Factory could not create an adequate instance of Tokenizer for dtype:{} !",dtype.name());
}
return new DefaultTokenizer();
}
}
您可以将Tokenizer(s)
的界面定义为:
public interface ITokenizer {
public void tokenizeData(Filename datablob);
}
...由您的抽象类AbstractTokenizer
实现,所有子类(例如TokenizerV1
和TokenizerV2
)将仅重新定义自定义抽象方法。就像下面的示例(基于@Lucas Oliveira提案)一样:
public abstract class AbstractTokenizer implements ITokenizer {
@Override
public void tokenizeData(Filename datablob) {
// convert filename
// open file
// handle file errors
// other code
tokenizedData = tokenizer( data );
// parsing and collection code
// more error processing code
// cleanup code
}
abstract TokenizedData tokenizer( Data cleansedData ); // << redef. by subclasses.
}
但它对你来说是透明的。
您最终可以使用TokenizerFactory,只需为主要业务方法提供一个预配置的参数,或者即使您拥有参数化所需的参数,也可以即时使用它们。因此,getInstance()
调用将返回您需要'tokenizeData()'的确切Tokenizer
。
注意:对于高度参数化的工厂,将它们与Builder(模式)相结合通常可以节省生命。
答案 1 :(得分:0)
Template Method似乎正在寻找什么。
它让你:
在操作中定义算法的框架,将一些步骤推迟到客户端子类。模板方法允许子类重新定义算法的某些步骤而不改变算法的结构。
基类声明算法'占位符',派生类实现占位符。
这是通过Abstract类完成的。您应该确定算法的哪些步骤是不变的(或标准的),哪些是变体的(或可定制的)。不变步骤在抽象基类中实现,而变量步骤可由oncrete派生类提供。
在你的情况下,事情就是这样:
abstract class AbstractTokenizer {
public void tokenizeData(final Object datablob) {
// convert filename
// open file
// handle file errors
// other code
tokenizedData = tokenizer( cleansedData );
// parsing and collection code
// more error processing code
// cleanup code
}
abstract TokenizedData tokenizer( Data cleansedData );
}