2017-12-06 56 views
1

私はOpenGL変換に必要な数学を行うための簡単なクラスを作ろうとしています。しかし、ここで私は途中で、さまざまな例を見ているうちに、ほとんどの図書館は行列クラスそのもの(静的メソッドを使った数学クラスのほとんどの時間)から数学を分離していることがわかります。これはどういう理由がありますか?マトリックスデータと数学を分けるべきですか?

複数の行列オブジェクトを作成しているときに、その関数も複数回作成されている場合は、パフォーマンスに影響するか、それとも完全に何かに影響しますか?

例: 数学関数を行列クラスに追加するほうがずっと簡単なので、行列自体を関数に渡す必要はありません。代わりに

public class LinearAlgebraMath { 
    public static Matrix4f rotate(Matrix4f target, double theta) { 
     target.setValue(0, 0, (float) Math.cos(theta)); 
     target.setValue(1, 0, (float) Math.sin(theta)); 
     target.setValue(0, 1, (float) Math.sin(theta)); 
     target.setValue(1, 1, (float) Math.cos(theta)); 
     return target;  
    } 
} 

public class Matrix4f { 

    //constructor... 

    //getters and setters... 
} 

class Matrix4f { 

    //constructor... 

    public void rotate(double theta) { 
     setValue(0, 0, (float) Math.cos(theta)); 
     setValue(1, 0, (float) Math.sin(theta)); 
     setValue(0, 1, (float) Math.sin(theta)); 
     setValue(1, 1, (float) Math.cos(theta)); 
    } 

    //getters and setters... 
} 

だから、最後に私はそれが私のために簡単ですので、複数のデータ構造を使用する算術演算を扱うを扱う場合は特に(マトリックスクラスに数学関数を追加することが好き)しかし、私は私の質問があるので、私の環境設定を低性能にしたくありません:上記の例を上回る例は上の例を上回っていますか?あなたは行列の複数を作成しているとき

+0

'rotate'は回転を行わないことに注意してください。代わりに行列を回転行列にします。クラス自体にメソッドを追加する方が、Javaでは多くのオブジェクト指向(OO)であり、より一般的です。パフォーマンスの差はまったくありません。あなたがそれらの名前を正しく指定していることを確認してください。 – maaartinus

+0

静的メソッドを使用してガベージコレクションのパフォーマンスの問題を回避しようとしていませんか? – jeff6times7

答えて

1

がそれです 機能も影響が完全に または何か他のものを、パフォーマンスを複数回、作成されていることをオブジェクト?

これらの機能は、VMにロードされたClassオブジェクトの一部です。複数のMatrixオブジェクトは、その関数/メソッドの1つのコピーのみを参照します。したがって、メモリなどは、あなたが提案しているようにインスタンスメソッドを使用することによって影響を受けることはありません。

私は通常、あなたが提案しているように、クラスのインスタンスに機能をアタッチします。おそらく、あなたが使用しているリファレンスは、構造体が行列に使用されていた非OO言語(C?)から翻訳され、スタンドアロン関数は必須であったでしょうか?

+0

ありがとう、OpenGLで使用するためにCから翻訳されている可能性があります。 –

+0

私は1つのクラスにデータとロジックを保持することに同意しません。 Matrix4fクラスは、データを保持し、計算を実行するサービスを作成するエンティティとして保持します。別の行列を回転させる必要がある場合はどうなりますか?独自のrotateメソッドを使用して別のタイプの行列を作成しますか?コードをより小さなクラスに分解する方がよいでしょう。 – CrazySabbath

0

非メンバーには、カップリングが緩やかであるという実用的な利点があります。彼らは話すために、クラスの内部を変更することはできません。

例として、行列に関するコードを使用してアプリケーションが一般的な配列アクセス例外(ユーザーのマトリックスクラスに固有のものではない)をスローしたユーザーから報告されたバグを発見した場合、あなたの母親が眠っている容疑者のあなたのリストは非常に狭く、その生殖器(私物)を混乱させる可能性のあるいくつかの方法しかない非常に単純なマトリックスクラスです。一方、200のメソッドを持つ行列クラスを持っていて、それがパーティーであり、酔っぱらいになり、穴があるものすべてで眠っているなら、調査する容疑者リストは巨大です。

また、人間に知られているすべてのマトリックス関連の操作を提供することを目的としていない場合は、コードの安定性(コンクリートでのセメントのように、さらに変更する理由がない) 。これは、パブリックインターフェイスが、あなたが戻ってきて、クラスの獣を持っているところに何度も無限に追加する誘惑を感じない真の "完了"のポイントを持っていることを確認するために何かを設計するときに非常に役に立ちます20ページにわたる文書を含む100以上のメソッドがあります。コードベースを安定した(変更されていない)部分と不安定な(変更されている)部分に分けることができるのは良いことです。どんなデザインであれ、非常に有限で提供される機能については "完全性"の状態を達成できるはずです 時間です。

可能な限りの操作をクラスに追加することを念頭において、クラスそのものに目標を達成できないことがよくあります。あなたがクラスに追加することがますます増えればするほど、もっと多くの理由を見つけることができます。あなたが追加するほど、あなたのデザインが不完全に見えてくるような悪循環があります。ミニマルはその目標に逆らう方法です。

そして最終的には、あなたのバットから離れていくことが少ないときに、あなたのマトリックスクラスが使い方を理解しやすくなります。いくつかの人々は固有ベクトル/値に興味を持たないかもしれないので、より少ない機能を提供すればあなたのインターフェースをより分かりやすくするのに役立つかもしれません。

実用的なアプローチは、行列/行列や行列/ベクトルの乗算など、すべてのバックグラウンドの人々が常に行う基本的な操作をデザインに組み込むことです。そこには、世界で想像できるすべてを行うことを目的とした神のクラス/モノリスをデザインすることなく、ある時点でデザインを「完了」することができるチェックリストがあります。次に、エキゾチックなものを、マトリックスのパブリック・インターフェースを通してしか動作できない静的メソッドを持つ別々のクラスのような、別々のインターフェースに入れます。これらの独立した静的メソッドは、内部クラスへのアクセスを持たないため、例えば、あなたのマトリックスクラスが、内部データに範囲外でアクセスすることを禁止する不変条件を課すことができる安全レイヤーを通過することができます(MatrixOutOfBounds例外を投げます)。この効果。

あなたのケースでは、方法が不可能なC APIであるOpenGLを使った単なる1対1の翻訳だと思っていますが、非メンバは一般的なソフトウェアエンジニアリングの観点からカップリングと結束という点で優れています。構文的には面倒かもしれませんが、クラスの秘密にアクセスできるものが少ないほど、メンテナンスとデバッグの観点から優れています。あまりにも多くのものが潜在的にそれらを改ざんする可能性があるような壮大なスコープ/可視性を持っているので、メソッドが非常に多く、あなたの秘密がグローバル変数に似ています。クラスのパブリックインターフェイスのみを使用して他の場所に実装できる場合は、クラスに何かを直接追加することを省略する理由を探すために、任意の言語でクラスを設計する際に留意すべきことがあります。同様の理由から、保護されたメンバにアクセスするためにクラスから継承することを避けることができれば、結合が緩やかになるため、SEの観点からは継承よりも継承よりも優れています。

パフォーマンスの観点から、最も効率的なソリューションはクラスの内部へのアクセスを必要とする可能性があるため、メソッドをクラスに直接追加する理由が多い傾向があります。まだ不必要なメソッドのボートを事前にクラスに追加するよりも、その必要性が強く認識されている場合には、新しい方法を追加する側を誤った方が良いです。私は、インターフェイスにメソッドを追加するかどうかについて、「疑わしいときは、それを放置してください」という単純なルールにしたがいます。

関連する問題