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";
        }
    };

しかし、問題は、シータを提供する必要がない場合があるため、シータを削除するとポリモーフィズムが機能しないことです(10のうち2つの関数はシータを必要としません)。醜い)それで、実際にnetsumとthetaの両方を含むObject全体を渡すことを考えました。

しかし、私は心配し始めています。なぜなら、この関数が実際に何のためにあるのかを台無しにしてしまうからです。したがって、最後に、これらの関数を別々に(匿名ではない)配置し、匿名関数にそれらを使用させることを提案しましたが、引数はオブジェクトになります。次のように:

 /** 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ですか?シータへの参照がある場所でインスタンスをインスタンス化できる場合は、匿名クラスがそのシータ参照を使用できます。例えば:

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

または、入力をジェネリック型として指定して、MyObject可能なすべての入力のスーパーセットである必要はなく、TransferePatternable型によって異なるようにすることもできます。明らかに、ここでの欠点は、正しい入力を提供するために呼び出しているタイプを知る必要があることですが、状況によってはシータを提供したくない場合は、とにかくこれを知る必要があります。

最後に、この問題のもう1つの一般的な解決策は、すべてのメソッドパラメータを1つだけに置き換えることMapです。その後、あなたはあなたが望むものを渡すことができます!これには明らかな欠点がたくさんありますが、多くのAPIはまさにこれを実行し、通常、マップを「コンテキスト」と呼んでいることがわかります。次にいくつかの例を示します。

私自身Map、何年も前にJavaでExcelのような数式言語を実装するときにこのソリューションを使用しました。このような式は関数と変数に解析でき、関数を実行するときに、Map変数名でキー設定された変数を含むを提供しました。明らかに、あなたはまだあなたが呼び出しているものについて何かを知る必要があります、そして実際、私たちは常に正しい入力を提供するのMapが簡単であるという公式について十分に知っていました。しかし、ここでも注意する必要があります。この種のコードは、実装と保守がかなり困難です。時間の経過とともに大量の関数セットが成長することを予期しない限り、このルートをたどらないでください。これはOOに適したものではなく、最後の手段になるはずです。

于 2011-08-30T03:27:15.893 に答える
1

MyObjectが一般的に使用されるインターフェイスまたはクラスでありTransferePatternable、他のものと連携することが期待されていない場合は、2番目のアイデアが最適です。これにより、TransferePatternableがnetSumとシータだけでなく不要なシータを取り除くことができる可能性が広がります。MyObjectクラス/インターフェイスの機能とスコープおよび重要性を拡張することを意味する場合でも、これがあなたがやりたいことだと思います。

ただし、TransferePatternableをMyObjectインスタンスでの作業に制限しています。未使用のシータは問題ですが、ポリモーフィズムの力を支払うのは小さな代償です(そして、他のほとんどのソリューションよりもはるかにシンプルできれいです)。MyObjectソリューションが完璧に見えない場合は、未使用のシータを使用してください。私の推測では、遅かれ早かれ実現するのは良い考えであり、そうでなくても害はありません。

于 2011-09-02T20:05:02.593 に答える
0

HARDLIMでオーバーロードされた「転送」機能を使用できない理由はありますか?

/** 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

最後に、2番目の選択肢を使用しましたが、いくつかの注意事項を念頭に置いています。

  1. ユーティリティクラスで常に独立して定義された関数(つまりHardlim)を持つこと。
  2. Javadocで、この変数が実際に何であるか、および使用されているユーティリティ関数を述べること。
  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 に答える