java—类的“set”方法应该返回“void”还是“boolean”?

e5njpo68  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(483)

所以我在设计一个类的时候经常遇到这个问题:

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 ,现已更正

sg24os4d

sg24os4d1#

以上都不是。
按照惯例,设置者会返回 void ,但可以返回示例的类型(在本例中为 Foo ,不是 Bar )如果实现一个fluent接口,那么setter方法的最后一行 return this; . (您的示例缺少一个返回,因此无法编译)。
如果setter的参数必须是“valid”,则不应影响返回类型。相反,方法应该爆炸:

public void setBar(Bar bar) {
    if (!validateBar(bar)) {
        throw new IllegalArgumentException("Bar is invalid");
    }
    this.bar = bar;
}

在这里不返回布尔值的一个很好的理由是,调用者可能不会检查返回值,并且可能会盲目地继续,就好像一切正常一样,这当然是不好的。
此外,最好是不可能创建一个无效的 Bar 通过移动 validateBar() 内部 Bar 构造函数,抛出一个 IllegalArgumentException 如果传入的参数将创建无效的 Bar ,则可以从中删除支票 Foo .
如果 validateBar() 方法是 static 意思是a Bar 可以在没有 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)` ,因为参数的类型清楚地表明了要验证的内容。

相关问题