如何设计扩展 [英] Howto design for extension
问题描述
Checkstyle 规则 DesignForExtension 。它说:如果你有一个公共/受保护的方法,它不是抽象的,也不是最终的也不是空的,它不是为扩展而设计的。在Checkstyle页面上阅读此规则的说明了解原理。
There is a Checkstyle rule DesignForExtension. It says: if you have a public/protected method which is not abstract nor final nor empty it is not "designed for extension". Read the description for this rule on the Checkstyle page for the rationale.
想象一下这种情况。我有一个抽象类,它定义了一些字段和这些字段的验证方法:
Imagine this case. I have an abstract class which defines some fields and a validate method for those fields:
public abstract class Plant {
private String roots;
private String trunk;
// setters go here
protected void validate() {
if (roots == null) throw new IllegalArgumentException("No roots!");
if (trunk == null) throw new IllegalArgumentException("No trunk!");
}
public abstract void grow();
}
我还有Plant的子类:
I have also a subclass of Plant:
public class Tree extends Plant {
private List<String> leaves;
// setters go here
@Overrides
protected void validate() {
super.validate();
if (leaves == null) throw new IllegalArgumentException("No leaves!");
}
public void grow() {
validate();
// grow process
}
}
继Checkstyle之后规则Plant.validate()方法不是为扩展而设计的。但是在这种情况下如何设计扩展?
Following the Checkstyle rule the Plant.validate() method is not designed for extension. But how do I design for extension in this case?
推荐答案
该规则正在抱怨,因为派生(扩展)类可以在不告诉您的情况下完全替换您提供的功能关于它。这是一个强有力的迹象,表明您还没有充分考虑如何扩展类型。你想要做的是这样的事情:
The rule is complaining because it is possible for a deriving (extending) class to completely replace the functionality you provided without telling you about it. It's a strong indication that you haven't fully considered how the type might be extended. What it wants you to do instead is something like this:
public abstract class Plant {
private String roots;
private String trunk;
// setters go here
private void validate() {
if (roots == null) throw new IllegalArgumentException("No roots!");
if (trunk == null) throw new IllegalArgumentException("No trunk!");
validateEx();
}
protected void validateEx() { }
public abstract void grow();
}
请注意,现在有人仍然可以提供自己的验证码,但他们可以'替换您预先编写的代码。根据您打算如何使用验证
方法,您也可以将其设为公开最终版。
Note that now someone can still supply their own validation code, but they can't replace your pre-written code. Depending on how you meant to use the validate
method you could also make it public final instead.
这篇关于如何设计扩展的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!