我在Java项目中使用合同。 (合同=在方法的开始和结束时进行检查)
我想知道是否有一种很好的方式/模式来编写泛型方法的合同。例如:
public abstract class AbstractStringGenerator{
/**
* This method must return a new line as it's last char
* @return string output
*/
public abstract string generateLine(String input);
}
我想要的是检查generateLine
的输出是否满足合约的好方法(在这种情况下,最后一个char必须是新行char)。
我想我能做到这一点(但我想知道是否有更好的方法);
public abstract class AbstractStringGenerator{
public string generateLine(String input){
string result = generateLineHook(input);
//do contract checking...
//if new line char is not the last char, then throw contract exception...
return result;
}
/**
* This method must return a new line as it's last char
* @return string output
*/
protected abstract string generateLineHook(String input);
}
希望这不是太模糊。任何帮助表示赞赏。
答案 0 :(得分:3)
这看起来像是使用Template Method design pattern的地方。使用模板方法模式,可以在抽象类中实现和最终确定通用算法,而某些细节可以在子类中实现。
为了实现Template方法:
模板方法可以在您的示例中实现为
public abstract class AbstractStringGenerator{
// marked as final. Subclasses cannot override this behavior
public final String generateLine(String input){
String result = generateLineHook(input);
//do contract checking...
//if new line char is not the last char, then throw contract exception...
if(!result.endsWith("\n")){
throw new IllegalStateException("Result from hook does not contain new line");
}
return result;
}
/**
* This method must return a new line as it's last char
* @return string output
*/
protected abstract string generateLineHook(String input);
}
public class ConcreteStringGenerator{
/**
* This method overrides the beh
* @return string output
*/
protected String generateLineHook(String input){
return "blah\n";
}
}
答案 1 :(得分:1)
就是这样。你必须创建你的方法并在其上使用final
修饰符,这样任何人都无法重写合同。在这种方法中,您检查合同并调用内部方法(您的generateLineHook(String)
),无需再做任何事情。
答案 2 :(得分:1)
我相信这样做很好,只记得在公共方法中添加“final”,这样子类就无法覆盖你的检查。
答案 3 :(得分:0)
我经常使用代码合约,有时会有很好的定义和自我描述的方法,很难签订合同。
我不知道Java(我假设您正在使用iContract等),但在C#/ Code Contracts中我会这样做:
Contract.Ensures(result[result.Length-1] == @"\n");
或类似的......
我不确定你有什么更好的方法来表达你的意思。