3

情况是我必须为Java中的这么多函数使用函数指针(所以我这样做了并将每个匿名类保存到接口的静态变量中,以便我可以直接使用它们。

 /** The Constant HARDLIM. */
    public static final TransferePatternable HARDLIM =
    new TransferePatternable() {
        public DoubleMatrix transfere(DoubleMatrix netSum, double theta) {
        return netSum.gt(theta);
        }
        public String getFuncName() {
        return "HARDLIM";
        }
    };

但问题是有时我不需要提供 Theta,所以如果我删除它,多态性将不起作用,(10 个函数中有 2 个不需要 theta)所以我不得不把它(函数声明约定现在丑陋的)所以我想传递实际上包含netsum和theta的整个对象。

但我开始担心,因为它也会破坏这个功能的真正用途。所以最后我建议我把这些函数分开(非匿名),然后让匿名函数使用它们,但参数是对象。如下所示:

 /** The Constant HARDLIM. */
    public static final TransferePatternable HARDLIM =
    new TransferePatternable() {
        public DoubleMatrix transfere(MyObject obj) {
        return MyObjectUtilFun.hardlim(obj.getNetsum,obj.getTheta);
        }
        public String getFuncName() {
        return "HARDLIM";
        }
    };

那么我是否采取了正确的步骤?或者我在胡闹,请指导我!

4

4 回答 4

2

你真的需要实例public static final吗?如果您可以在引用 theta 的任何地方实例化实例,那么您的匿名类可以使用该 theta 引用。例如:

final double theta = 123d;
class TransferePatternable {
    public String transfere(String whatever) {
        return whatever + theta;
    }
}
TransferePatternable myInstance = new TransferePatternable();
myInstance.transfere("arg");

或者,您可以将输入指定为通用类型,这样您MyObject就不必是所有可能输入的超集,而是可以因 TransferePatternable 类型而异。显然,这里的缺点是您需要知道要调用的类型才能提供正确的输入,但是如果您不想在某些情况下提供 theta,则无论如何您都需要知道这一点。

最后,这个问题的另一种常见解决方案是将所有方法参数替换为一个Map. 然后,你可以传入任何你想要的东西!这有很多明显的缺点,但是很多 API 正是这样做的,通常你会看到它们将地图称为“上下文”。这里有一些例子:

  • javax.servlet .ServletRequests 将参数存储在Map
  • AOP 有javax.interceptor.InvocationContext
  • Spring 的 IoC 容器基本上是Map一大堆命名的 javabean
  • JSP 表达式语言允许您引用基本上存储在几个s中的隐式对象Map

几年前,我自己Map在 Java 中实现类似 Excel 的公式语言时就使用了这个解决方案。这样的公式可以解析为函数和变量,并且在执行函数时,我们提供了一个Map包含以变量名称为键的变量。显然,您仍然需要了解您正在调用的内容,事实上,我们总是对在 a 中提供正确输入Map很容易的公式有足够的了解。但我必须再次提醒您:这种代码很难实现和维护。除非您预计随着时间的推移会增加大量功能,否则不要走这条路。它不是面向对象友好的,它应该是最后的手段。

于 2011-08-30T03:27:15.893 回答
1

如果MyObject是一个常用的接口或类,并且TransferePatternable预计不会与其他任何东西一起使用,那么您的第二个想法是最好的。它开启了 TransferePatternable 的可能性,不仅可以使用 netSum 和 theta ,还可以摆脱不需要的 theta。我的猜测是,这就是您想要做的,即使这意味着扩展 MyObject 类/接口的功能、范围和重要性。

但是您将 TransferePatternable 限制为使用 MyObject 实例。未使用的 theta 是一个问题,但它为多态性的力量付出了很小的代价(而且它比大多数其他解决方案更简单、更整洁)。如果 MyObject 解决方案对您来说并不完美,请坚持使用未使用的 theta。我的猜测是一个好主意迟早会出现,如果没有,也不会造成任何伤害。

于 2011-09-02T20:05:02.593 回答
0

有什么理由不能在 HARDLIM 中使用重载的“transfere”功能吗?

/** The Constant HARDLIM. */
public static final TransferePatternable HARDLIM =
new TransferePatternable() {
    public DoubleMatrix transfere(DoubleMatrix netSum, double theta) {
    return netSum.gt(theta);
    }
    public DoubleMatrix transfere(DoubleMatrix netSum) {
    return netSum.whateverYouNeedToDoWithoutTheta();
    }
    public String getFuncName() {
    return "HARDLIM";
    }
};
于 2011-08-29T22:58:04.470 回答
0

最后我使用了第二个选项,但要记住一些注意事项:

  1. 始终在实用程序类中独立定义函数(即 Hardlim)。
  2. 在 Javadocs 中说明这个变量到底是什么以及正在使用的效用函数。
  3. 我还发现用不必要的参数混淆用户的代价很高,因为应用程序已经很复杂,不需要再复杂了。

    public static final TransferePatternable HARDLIM =
    new TransferePatternable() {
        public DoubleMatrix transfere(MyObject obj) {
        return MyObjectUtilFun.hardlim(obj.getNetsum,obj.getTheta);
        }
        public String getFuncName() {
        return "HARDLIM";
        }
    };
    
于 2011-09-13T14:04:31.377 回答