有没有比通过传递参数更好的方法来确定方法的行为?

时间:2018-01-20 11:27:14

标签: java function-pointers strategy-pattern

最小的工作示例:

static void foo(boolean bar){
   some code A
   if(bar){
      some code B
   }
   else{
      some code C
   }
   some code D
}

这里我们使用参数栏来确定方法的行为,而不是实际对其值进行某些操作。因此,我们会冗余地检查bar的值。调用foo() 的方法知道 bar的值,因为它实际上将其作为参数传递。一个简单的替代方案是:

static void foo1(){
   A;B;D;
}

static void foo2(){
A;C;D
}

结果是,我们有冗余代码。现在我们可以将A和D放入方法中,但是如果它们操纵了几个变量呢? Java没有多种返回类型的方法。即使假设我们可以将它们放入方法中,我们仍然会foo1看起来像a();b();d(),而foo2看起来像a();c();d()。我目前解决这个问题的方法是为c(), b()创建一个功能接口,然后将foo定义为

static void foo(BCinterface baz){ A; baz.do() ;D;}

问题是每次我想编写一个行为略有不同的方法时,我必须为它们不同的方法定义一个接口。我知道在其他语言中有函数指针。有没有办法在java中实现类似的东西而不必每次都定义一个接口?或者是否有一些练习可以避免首先出现这种情况?

2 个答案:

答案 0 :(得分:1)

事实上,我认为您的第一个代码段是最佳和最易读的解决方案。

bar用于确定方法将执行的操作,那么什么?为什么要尝试将此逻辑移动到foo的调用者?无关紧要。如果我试图阅读foo的来电者,我是否需要知道foo如何运作(鉴于它的名字很好)?不。因为我只对foo的来电者发生的事情感兴趣。抽象是一个的东西,而不是坏事。所以我的建议是,保持原样。

如果您真的想要提取逻辑,那么每次都不需要新的功能界面。 java.util.function包和java.lang包已经为您提供了一些功能接口。只需使用它们。例如,在您的具体情况下,BCInterface可以替换为Runnable

答案 1 :(得分:0)

你解决重复调用的方式似乎过于复杂 要在处理/算法的特定步骤中提供不同的行为,您可以简单地使用依赖于抽象方法和多态的the template method pattern

  

在软件工程中,模板方法模式是一种行为   设计模式,定义一个算法的程序骨架   操作,将一些步骤推迟到子类。1它让一个人重新定义   算法的某些步骤而不改变算法   结构。[2]


当然,您必须删除所有不允许利用OOP功能的static修饰符。
不再需要boolean参数。

在基类Foo中定义,foo()定义依赖于抽象方法的一般行为,并让子类定义抽象方法实现。

public abstract class Foo{

    public abstract void specificBehavior();   

    public void foo(){
       a();
       specificBehavior();
       d();
    }

   public void a(){
      ...
   }

   public void d(){
      ...
   }

}

现在是子类:

public class  FooOne extends Foo {
  public void specificBehavior(){
      ...
  }
}

public class FooTwo extends Foo {
  public void specificBehavior(){
      ...
  }
}