所以我在设计一个类的时候经常遇到这个问题:
class foo {
private Bar bar;
public foo(Bar bar) {
this.bar = bar;
}
public Bar getBar() {
return bar;
}
public void setBar(Bar bar) {
this.bar = bar;
}
}
到目前为止,还不错,对吧?但是我想“我怎么知道用户会通过一个可接受的 bar
反对?那么:
private bool validateBar(Bar bar) {
return amIgood(bar);
}
好吧,我当然需要把这个和 setBar
功能如下:
public bool setBar(Bar bar) {
if (validateBar(bar)) {
this.bar = bar;
return true;
}
else
return false;
}
好吧,如果这是我需要做的,那么我也必须包含在构造函数中,对吗?除了构造函数没有返回 foo
对象,所以我试着想出一些解决办法,比如:
public foo(Bar bar) {
if validateBar(bar)
this.bar = bar;
else
throw Exception("Invalid bar passed along to foo");
}
或:
public foo(Bar bar) {
if (!setBar(bar))
throw Exception("Invalid bar passed along to foo");
}
你可以看到一些简单的事情是如何很快失去控制的。如果在验证的基础上还要做一些卫生工作,那就更糟了。
所以我的问题是如何在保持类结构相对简单的同时处理验证问题?
编辑的第一个示例 setbar
应该是的 void
但不小心 bar
,现已更正
1条答案
按热度按时间sg24os4d1#
以上都不是。
按照惯例,设置者会返回
void
,但可以返回示例的类型(在本例中为Foo
,不是Bar
)如果实现一个fluent接口,那么setter方法的最后一行return this;
. (您的示例缺少一个返回,因此无法编译)。如果setter的参数必须是“valid”,则不应影响返回类型。相反,方法应该爆炸:
在这里不返回布尔值的一个很好的理由是,调用者可能不会检查返回值,并且可能会盲目地继续,就好像一切正常一样,这当然是不好的。
此外,最好是不可能创建一个无效的
Bar
通过移动validateBar()
内部Bar
构造函数,抛出一个IllegalArgumentException
如果传入的参数将创建无效的Bar
,则可以从中删除支票Foo
.如果
validateBar()
方法是static
意思是aBar
可以在没有Foo
因此,逻辑应该在Bar
-Foo
不应负责或不知道如何验证Bar
如果不需要的话。但是,如果
Foo
对有效的Bar
如果在其他地方不适用,请创建Bar
例如FooBar extends Bar
,实现Foo
的特殊验证要求,同样在其构造函数中。如果验证
Bar
是否需要Foo
验证和重用Bar
示例之间Foo
s不是必需的,则Bar
类应该是Foo
,在这种情况下,验证仍然可以在栏中进行constructor, and the state of the containing
foo根据需要可用于验证逻辑。 如果验证
Bar需要一个
Foo验证和重用
Bar示例是必需的,那么
Bar不能是内部类,验证代码应位于
Foo就像你和你的朋友建议的那样
validateBar(Bar bar)方法,除非它不是
static所以这个方法会有
Foo使用。 另外,考虑重新命名
validate(Bar bar)` ,因为参数的类型清楚地表明了要验证的内容。