2011-07-10 11 views
1

これはグラフィックスの問題よりも設計上の問題ですが、ここでは少し背景があります:OpenGLを使ってJavaでJOGLを使ってメッシュを読み込むプログラムを書いています.objファイルから取得してレンダリングします。これまでのところ問題はありませんが、一連のフィルターや変換をメッシュに適用できる必要があります。異なるパラメータを持つメソッドのインタフェースを設計する

  • 騒々しいメッシュ
  • 又は平滑メッシュとの両方に基づいてもしなくてもよいメッシュ(着色にスムージングアルゴリズムを適用する頂点
  • にランダムノイズを加える面
  • テッセレーションオリジナルクリーンメッシュ)

これらのフィルタのいくつかは、順番に適用されます。私はまた、他の人が(おそらく一般的な)独自のフィルターを書くために、一種の一貫したインターフェースを提供したいと思っています。私はこれについてどうやって行くのですか?

主な問題は、フィルタが異なるパラメータセットを必要とすることです。 1つのスムージングアルゴリズムでは、ユーザーが(実行時にGUIを使用して)2つのパラメータを選択する必要がありますが、別のパラメータを必要としない場合もあります。同様に、いくつかのカラーリングアルゴリズムでは平滑化メッシュとRGBカラーのみが必要な場合があり、別のカラーリングアルゴリズムでは平滑化メッシュとクリーンメッシュの両方が必要になることがあります。だから、呼び出しは次のようになります。

mesh = smoothingFilter1.filter(mesh, booleanParam); 

が、それは完全に異なる場合があります:

mesh = smoothingFilter2.filter(mesh, intParam1, intParam2, floatParam); 

明らかに私のコードは、一般的なフィルタリング方法を呼び出すことが可能である必要があります。何らかの種類の制御クラスでそれ自体(および必須のパラメータ)を登録する実装されていないメソッドを持つFilterの抽象クラスまたはインターフェイスを定義することは良い考えですか?かなり複雑に思えますが、プログラムに任意の署名を持つフィルターメソッドを使用させる他の方法は考えられません。私はこの考えがうまくいくかどうかもわかりません...

このような状況を処理するためのデザインパターンはありますか?

+0

おかげ

// Foo filter public Mesh filter(Mesh inMesh, FilterParameters fp) { if (!(fp instanceof FooFilterParameters)) { throw new IllegalParameterException("Not FooFilterParameters."); } // Foo filter code here. } 

ロッサム:

// Foo parameter only. class FooFilterParameters extends FilterParameters { public Foo getFoo() { } // Other stuff. } // Foo, Bar and int parameters. class BarFilterParameters extends FilterParameters { public Foo getFoo() { } public Bar getBar() { } public int getMagnification() { } // Other stuff. } 

各フィルタ方法は、そのパラメータの種類を確認する必要があります –

答えて

4

実際には、パラメータはまったく必要ありません。 Mesh filter(Mesh mesh);で十分です。 他のパラメータを、フィルタのさまざまな具体的な実装のコンストラクタに移動します。

このようなものになります:あなたはの線に沿って何かを使用することができますインスタンス化するため

Filter smoothingFilter1 = new FirstFilter(booleanParam);  
mesh = smoothingFilter1.filter(mesh); 

Filter smoothingFilter2 = new SecondFilter(intParam1, intParam2, floatParam);  
mesh = smoothingFilter2.filter(mesh); 

を:

public interface AbstractFilterFactory { 
    Params getRequiredParams(); 
    Filter createFilter(Params params); 
} 

public interface Params { 
// some interface that describes specific parameters that are required 
// probably a collection of Parameter classes which has name, type and value information. 
} 

public class FirstFilterFactory implements AbstractFilterFactory { 
    // return a concrete params object use that to instantiate a concrete filter. 
} 
+0

ありがとう、それは少し楽になりますが、実行時にパラメータが異なる可能性があり、フィルタを作成するコード(つまり、適切なパラメータを持つコンストラクタを呼び出すコード)が、ユーザーのコードではなく、 。また、私のコードでは、GUI上にどのようなコントロール(スライダなど)とパラメータ名を付けて、入力として必要なパラメータを事前に知る必要があるかを知る必要があります。 –

+0

@HappyPixelは、コンストラクタをカプセル化する手段をいくつか追加しました。 –

+0

@M Platvoetああ、賢いです、もう一度ありがとう! –

1

(私はひどく熱心じゃない)別のアプローチは、バンドルすることですオブジェクト内のパラメータを上げ、異なるオブジェクトに対して異なるパラメータを渡すために多態性を使用します。

まず、迅速かつ汚いバージョン、マップを使用して:

interface Filter { 
    Mesh filter(Mesh input, Map<String, Object> params); 
} 

ポリモーフィックオブジェクト:ジェネリックスルー型の安全性と

abstract class Parameters { 
} 

interface Filter { 
    Mesh filter(Mesh input, Parameters params); 
} 

class FirstFilterParameters extends Parameters { 
    private boolean booleanParam; 
    // constructor, getter, possibly setter 
} 

class FirstFilter implements Filter { 
    Mesh filter(Mesh input, Parameters params) { 
     FirstFilterParameters ffParams = (FirstFilterParameters)params; 
     boolean booleanParam = ffParams.getBooleanParam(); 
     // etc 
    } 
} 

ポリモーフィックオブジェクト:

abstract class Parameters { 
} 

interface Filter<P extends Parameters> { 
    Mesh filter(Mesh input, P params); 
} 

class FirstFilterParameters extends Parameters { 
    private boolean booleanParam; 
    // constructor, getter, possibly setter 
} 

class FirstFilter implements Filter<FirstFilterParameters> { 
    Mesh filter(Mesh input, FirstFilterParameters params) { 
     boolean booleanParam = params.getBooleanParam(); 
     // etc 
    } 
} 

バージョンしかしジェネリックでは、フィルタの多態的な扱いは難しくなります。フィルタのリストとパラメータのリストを持ち、それぞれのフィルタに対応するパラメータを適用するにはどうしますか?それを安全に行う方法はありません。 FilterWithParams<P extends Parameters>のような独自の型パラメータを持ち、List<FilterWithParams<?>>を持つオブジェクトに各ペアをパックするような操作をしなければならないでしょう。あなたは基本的にM. Platvoetのソリューションを再発明しました!

+0

すてきな答え。ジェネリックのソリューションは、私が受け入れられた答えよりも問題に適しているようです – LetsPlayYahtzee

1

ジェネリックせずに、別の同様のソリューションは、抽象パラメータクラスを宣言することです:あなたは新しい宣言に必要な各パラメータの新しいセットについて

interface Filter { 
    Mesh filter(Mesh input, FilterParameters params); 
} 

abstract class FilterParameters { } 

あなたのインターフェイスはその後のようになります。必要なすべてのパラメータを持つことができるFilterParametersのサブクラスです。ちょうどこのようなものを試しにラウンド持って、すべての3の回答有用であることが判明、応答のための

関連する問題