1

私は、さまざまな要素が同じ種類の「コンテキスト」を受け入れ/生成することに基づいた、ある種のフィルタリングシステムを作成しています。

たとえば、次のようにプロセスをモデル化できます。

{generate_numbers(1..100)} --> {is_prime} --> {output}

コンテキストは単純な「HashMap」にすることができます。generate_numbers'x' が何らかの数値に設定されたコンテキストを作成is_primeし、このコンテキストを使用して 'x' を探し、それに応じて 'prime'=true/false を設定します。

長所:

  • 柔軟性 (さらに簡単に拡張可能 (HashMap))

短所:

  • 型のない値はいたるところにキャストされます

すべてを「コンテキスト」のフィールドとして宣言することも実行可能なアプローチですが、この方法では簡単に拡張できることが犠牲になります(私はそれで暮らすことができます)


しかし...状況はもう少し複雑です。これは、これらの変換要素がアプリケーションのパッケージ全体に散らばっているためです。

{generate_numbers(1..100)} --> {is_prime} --> {calc(f_1)} --> {output}
{--------------- pkg_A ------------------} | {--------- pkg_B -------}

したがって、pkg_A が何らかの作業を行う部分があり、次に pkg_B 部分がコンテキストを処理する場所があります --> そのため、2 つの方法を混在させたいと考えています。


私は次のアイデアを思いつきました:

オプション1

  • コンテキスト E を含む基本的な HashMap に名前を付けたとします。
  • ゲッター/セッターが利用できるフィールドにいくつかのエントリが表示される E のサブクラスを作成します
  • すべての処理関数で、着信引数を必要なクラス型にキャストします

プロ:

  • 実装が比較的簡単

短所:

  • HashMap コンテンツとフィールドを同期する必要があります
  • 複数の方法で値にアクセスすると、混乱が生じる可能性があります

オプション 2

  • キャストを行ういくつかの「ツール」クラスを作成します

プロ:

  • すべての関数でサブクラスのランタイム キャストがない

短所:

  • アクセスは常に HashMap アクセスに変換されます
  • フィールドが読み取られるたびにキャストがあります

オプション 3

私は完全に間違っています。別の方法で問題に対処する必要があります

アップデート:

「コンテキストクラスを昇格させる方法は?」現在のワークフローでは、これらの情報は制御ロジックでぼやけているため、アプリケーションが作業しているすべての厄介なものを運ぶ比較的便利なコンテキストをどのように作成できるかを意味します

4

2 に答える 2

1

私はあなたがScalaに切り替えるべきだと信じています D。
Scalaは、Java仮想マシン上で実行され、今述べたことをサポートし、強力なパターンマッチングエンジンを備えたOOP設計の関数型言語です。

もう1つの方法は、Javaで関数型パラダイムをシミュレートすることです。これは、実際には数日前に頭に浮かびましたが、作業が多すぎて忘れてしまいました:D。

基本的に、私が彼らを振り返って考えていたのは、あなたがインターフェースを持っているべきだということです

public interface Functionalizable {
    public void map(Function f);
}

Function独自の関数を作成するために拡張できるインターフェースもどこにありますか。次に、そのような例の1つ(おそらく悪いですが、電車で仕事をするために旅行しているときの私の考えでした)は次のようになります。

public class FunctionList extends ArrayList implements Functionalizable {
    public void map(Function f) {
        // iterate over the elements of a list
        // applying the function f on each of them
    }
}

そして、あなたはそれをこのように呼ぶことができます:

List l = new FunctionList();
// add some data
l.map(
    new Function() {
        // some function
    }
)

もちろん、このコードはどれも実際にコンパイル可能ではありませんが、私が考えていたものだけを知っています。そうです、Javaに関数型パラダイムを導入するのは面倒なので、もう一度言いますが、私の最善のアドバイスは、Scalaのような実際の関数型言語に固執することです。:D

于 2012-07-14T10:54:28.853 に答える
0

メタデータを渡そうとすると、メンテナンスの頭痛の種になります。代わりに、関数型プログラミングソリューションが必要ですが、特にリスト内包表記を処理したいようです-あなたの例ではgenerate_numbers関数です。@Lopinaが示唆するように、関数オブジェクトのセットを作成することで、独自のロールを作成することでこれを行うことができますが、より良いパスは既存のJavaライブラリを使用することだと思います.

特に、Google Guavaには、この方法で Java コレクションに対して作業するためのツールが多数あります。関数型イディオムが必要です。Guavaのフレームワーク内で使用するには、独自の関数(この場合はGuava Predicates )を作成する必要がありますが、説明する問題に対して適切なツールと抽象化レベルを提供すると思います。この質問の回答は、 predicates を理解するのに特に役立ちました。

グアバコードの例

import java.util.Arrays;

import com.google.common.base.Predicate;
import com.google.common.collect.*;

public class PrimeFinder {
    static Predicate<Integer> isPrimeToTenThousand = new Predicate<Integer>() {
        private boolean[] primes = new boolean[10000];
        {
            // prime detection algorithm from
            // http://www.mkyong.com/java/how-to-determine-a-prime-number-in-java/
            // will contain true or false values for the first 10,000 integers
            Arrays.fill(primes, true); // assume all integers are prime.
            primes[0] = primes[1] = false; // we know 0 and 1 are not prime.
            for (int i = 2; i < primes.length; i++) {
                // if the number is prime,
                // then go through all its multiples and make their values false.
                if (!primes[i]) continue;
                for (int j = 2; i * j < primes.length; j++)
                    primes[i * j] = false;
            }
        }

        @Override
        public boolean apply(Integer number) {
            return primes[number];
        }
    };

    public static void main(String args[]) {
        ImmutableSortedSet<Integer> positiveIntegersTo100 = Ranges.open(1, 100).asSet(DiscreteDomains.integers());
        Iterable<Integer> primeNumbersTo100 = Iterables.filter(positiveIntegersTo100, isPrimeToTenThousand);
        // output: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
        System.out.println(primeNumbersTo100);
    }
}

最後に、 Java で Python リスト内包表記をシミュレートする方法に関するこの他の質問とその回答が役立つはずです。

于 2012-07-15T17:05:31.970 に答える