在Java中实现启用/禁用方法的最佳方法是什么?

时间:2011-04-17 05:36:17

标签: java exception methods boolean state

在Java中,给定一对公共方法enableFoo和disableFoo,它们分别将名为isEnabledFoo的布尔字段设置为true或false,如果方法在设置之前检查Foo是否已经启用?如果是,是否应该抛出异常?如果是,是应该检查还是取消选中?如果不加以控制,应该扔什么? IllegalStateException异常?

扭曲:虽然当前实现只是设置一个布尔字段,但我故意不将它实现为一个带有布尔参数的setFoo“setter”方法,因为稍后可能会改变实现以包含副作用(甚至可能不会总之设置一个字段)。保持enableFoo / disableFoo似乎是保证封装的最佳方式。

我应该这样做:

public void enableFoo() throws myCheckedException
{
  if (! this.isEnabledFoo)
  {
    this.isEnabledFoo = true;
  }
  // Is this overkill?
  else
  {
    // Foo is already enabled...Should a checked exception be thrown?
    throw new myCheckedException ("Foo is already enabled.");

    // What about an unchecked exception?
    // throw new IllegalStateException ("Foo is already enabled.");
  }
}

或者只是这样:

public void enableFoo()
{
  // I guess we don't care if foo is already enabled...
  this.isEnabledFoo = true;
}

甚至:

public void enableFoo()
{
  // Is this just code bloat?
  if (! this.isEnabledFoo)
  {
    this.isEnabledFoo = true;
  }
}

我认为虽然最后两个版本更简单,但它们会隐藏一个可能的错误,开发人员在调用enableFoo时认为它已被禁用,而实际上它已经启用了(但这真的很重要吗?)。这里最好的设计是什么?

5 个答案:

答案 0 :(得分:4)

我真的不认为你的问题有答案。所有这些看起来都是有效的,这取决于你正在进行的操作以及操作后对象的一致状态。

例如:我有一个方法可以启用语法高亮显示,如果你选择启用它并且它已经启用你会关心什么。在这种情况下,您只需设置布尔标志,而不管先前的状态(选项2)。

另一方面,如果我不只是更改一个布尔字段,而是执行一些复杂的逻辑,这可能是重新运行的昂贵,例如浏览文档的DOM并为所有正确的位置着色我不会想要再次这样做只是因为某人“重新检查”了启用标志。

这样的事情:

public void enableHighlighting() {
  if (!isHighlighting) {
    isHighlighting = true;
    colorView();  // very expensive method
  }
}

现在让我们假设您有一个双重启用反映机器状态不一致的情况(类似于您使用assert的情况。在这种情况下,您可能希望抛出异常来表示用户已执行此操作非法的东西。

例如,假设语法突出显示仅影响某些类型的文件(如XML或Java代码),并且用户尝试将其应用于PHP代码。现在突出显示已经启用,但受挫的用户尝试启用它,因为他没有看到任何更改。在这种情况下,您可能想要向用户打印消息,说明已启用突出显示。在这种情况下,更改是否发生的返回值可能更有意义,但您也可以使用异常。

返回值:

public boolean enableHighlighting() {
  prevState = isHighlighting;
  isHighlighting = true;
  return prevState != isHighlighting; //return true if value changed
}

答案 1 :(得分:0)

不。你为什么要关心? enableFoodisableFoo非常明确 - 一个启用,另一个禁用。无需检查当前状态。

如果你真的想要,可以返回一个表示先前状态的布尔值。您也可以使用public boolean isEnabled()方法。

答案 2 :(得分:0)

没有直接答案。这取决于要求。具体而言,您的操作是否是幂等的。

http://en.wikipedia.org/wiki/Idempotence

答案 3 :(得分:0)

如果您的程序是多线程的,建议使用锁定启用和禁用功能,如果锁不是原子的,则检查可能会有所帮助。否则你不必担心检查状态。

答案 4 :(得分:0)

您可以使用 Facet 来启用/禁用功能。

<块引用>

免责声明:我是该平台的作者之一

您可以将方面视为应用程序的所有方法。您可以在运行时启用/禁用方法。

如何整合:

  • maven central处拿包裹
  • 将其添加到 gradle 配置:implementation 'run.facet.agent.java:facet-agent:0.0.8'
  • 创建一个 facet.yml
workspaceId: WORKSPACE~ID
name: My-Application
environment: dev
apiKey: API_KEY

注意:您可以从 Facet dashboard

获取这些密钥
  • 集成完成后,您可以从系统实时启用/禁用方法。请注意,您无需重新部署或重新启动应用程序。

为了让您了解它与其他人提到的功能标志有何不同,您可以认为分面会自动应用于您的应用程序,而不是每次开发功能时都以编程方式声明。

注意:这还不是生产就绪的。很高兴与您一起解决问题!