创建采用布尔值isX并根据isY需要布尔值的构造函数的最佳实践是什么?

时间:2019-05-28 22:55:22

标签: java

在这个假设的问题中,我正在创建一个类来表示香肠,它可以是: A.新鲜和包装 B.新鲜且未包装 C.不新鲜也不包装

注意:它不能新鲜包装。

我正在寻找创建此构造函数的最佳实践。

我尝试的方法如下,但我认为应该有更好的解决方案。

public class Sausage {
    Meat meat;
    boolean isFresh;
    boolean isPackaged;

    public Sausage(Meat meat, Boolean isFresh, Boolean isPackaged) {
        this.meat = meat;
        if (!isFresh) {
            this.isFresh = false;
            this.isPackaged = false;
        }
        else if (isPackaged) {
            this.isFresh = true;
            this.isPackaged = true;
        }
        else {
            this.isFresh = true;
            this.isPackaged = false;
        }
    }
}

我正在寻找一种更清洁的方式来提供此功能。

3 个答案:

答案 0 :(得分:3)

您可以将可能的状态表示为枚举类型:

enum SausageType {
    FreshPackaged,
    FreshUnpackaged,
    NotFresh;
}

然后将构造函数更改为采用SausageType而不是两个Boolean

此方法的优点在于,不可能用错误的状态组合来调用构造函数,对于类的用户来说很明显可能的值是什么,并且您不必记住保持脆弱的运行时间根据需求的变化检查最新的参数。

答案 1 :(得分:1)

您当前的方法存在一些问题:

  1. 有一种方法可以创建写new对象,这没有任何意义,例如已打包的new Sausage(..., false, true)将被静默转换为false。这会造成混乱,并使代码更难以理解。

  2. 您正在混合Boolean对象类型和boolean基本类型,这将导致不必要的自动装箱。如果您不需要支持null,请使用boolean

  3. boolean字段可能不需要is前缀。

由于有两个布尔标志和四种可能的设置,它们可以设置(true truetrue falsefalse truefalse false),但是只有3个有效选项可能被命名为工厂方法会更合适:

public class Sausage {

    public static Sasuage newFreshPackaged(Meat meat) {
      return new Sasuage(meat, true, true);
    }

    public static Sasuage newFreshNotPackaged(Meat meat) {
      return new Sasuage(meat, true, false);
    }

    public static Sasuage newNotFreshNotPackaged(Meat meat) {
      return new Sasuage(meat, false, false);
    }

    private Sausage(Meat meat, boolean fresh, boolean packaged) {
        this.meat = meat;
        this.fresh = fresh;
        this.packaged = packaged;
    }
}

答案 2 :(得分:-1)

isPackaged更改为false可能会使调用代码感到惊讶。在这里,如果选择了组合(不是新鲜包装),则可以选择引发异常。

if (!isFresh && isPackaged) {
    throw new IllegalArgumentException("Can't be both not fresh and packaged!");
}
this.isFresh = isFresh;
this.isPackaged = isPackaged;

您还可以决定使用工厂方法(使构造函数为private)来满足您的要求。这样可以避免引发异常。

public static Sausage createFreshSausage(Meat meat, boolean isPackaged) {
    return new Sausage(meat, true, isPackaged);
}

public static Sausage createNotFreshSausage(Meat meat) {
    return new Sausage(meat, false, false);
}

偶然地,通常将原语boolean用于构造函数的参数类型,而不是像实例变量那样用于对象包装Booleannull允许的Boolean值没有任何意义。