如何根据对象情况设置对象的字段,而不依赖布尔标志?

问题描述 投票:0回答:2

我们有一个巨大的对象,它一一设置了很多字段。然而,我们已经达到了这样的地步:我们设置了 3 个标志,以便根据我们的需要创建它,这违反了干净的代码规则。基本上它看起来像这样:

method(boolean flag1, boolean flag2, boolean flag3){
    if (flag1){
        field1 = customValue1;
    }
    if (flag2){
        field2 = customValue2;
    }
    if (flag3){
        field3 = customValue3;
    }

我如何重构它,使其遵循标准(去掉所有标志)?

我认为为每种情况创建一个单独的方法是不行的,因为我会有很多代码重复(由于字段数量和业务逻辑的一般工作方式,该方法有超过 200 行代码)。然后我想到为每种可能的情况创建某种供应商对象,但是......只是没有。我有什么选择?

java oop design-patterns
2个回答
0
投票

我通常创建按位标志变量。 每个整数最多可以包含 32 个不同的“布尔”标志,因此如果我需要声明 33 个布尔值,我只在该类中创建 2 个整数。

class MyClass {
    static final int FLAG_NONE = 0;
    static final int FLAG1_ENABLED = 1;
    static final int FLAG1_OPENED = 1 << 1;
    static final int FLAG1_HEAVY = 1 << 2;
    ...
    static final int FLAG1_FLYING = 1 << 31; //max value for a single Integer

    private int mFlags1 = 0;
    private int mFlags2 = 0;

    MyClass addFlags1(int flags) { mFlags |= flags; return this; }
    MyClass removeFlags1(int flags) { mFlags &= ~flags; }
    boolean hasFlags1(int flags) { return ((mFlags1 & flags) == flags); }
    ...do the same for "flags2"....
}

通过这种方式,您可以一起或按顺序设置多个标志:

final MyClass cNewClass = new MyClass();
cNewClass
    .addFlags1(FLAG1_ENABLED)
    .addFlags1(FLAG1_OPENED);
cNewClass.removeFlags1(FLAG1_HEAVY | FLAG1_FLYING);
if (cNewClass.hasFlags1(FLAG1_OPENED) || !cNewClass.hasFlags1(FLAG1_FLYING | FLAG1_ENABLED)) { ... }

使用 ENUMS 可以实现相同的结果,但我更喜欢简单的整数位值。


0
投票

我如何重构它,使其遵循标准(去掉所有标志)?

您有多少个字段?您是否考虑过使用构建器方法?

class Foo (
   Foo setValue1(int v1) {
         valueV1 = v1;
         return this;
   }
   Foo setValue2(String v2) {
        valueV2 = v2;
        return this;
   }
   Foo setValue3(double v3) {
         valueV3 = v3;
         return this;
   }

然后根据需要调用链中的方法。

Foo foo = new Foo();
foo.setValue1(23).setValue2(4.3); 
© www.soinside.com 2019 - 2024. All rights reserved.