2013-06-26 3 views
5

私は小さなゲームをプログラミングしています。私はBoardPieceという2つのクラスを持っています。 BoardBoardのボーダーで移動できるPieceを持っています(これまでのところ)。オブジェクト自身(これ)をフィールドメソッドに渡すのは悪い方法ですか?

public class Board { 
    private Piece piece_; 
    private int width, height; 
    ... 

    movePieceDown() { 
    piece_.moveTo(this, 1, 2); 
    } 
} 

public class Piece { 
    public boolean moveTo(Board board, int x, int y) { 
    // move piece to new location (x,y) 
    // return true if successful 
    } 
} 

ボード上の障害物がない場合、私は理事会にpiece_.moveTo(this, 1, 2);パス参照でそうワンピースは、新しい場所に移動することができれば、それは悪いアプローチですか?ボードに言及することなく、ピースは新しい場所に障害があるかどうかを知ることはできません。

私の意見では、すべてのオブジェクトは自分自身についてのみ心配する必要があります。ピースは新しい場所に移動し、理事会は法的な動きであれば心配する必要がありますが、このサンプルコードはより意味があり、

TL; DR:フィールドのメソッドにオブジェクト自体を渡していくつかのOOPガイドラインを破っていますか、それとも通常のOOPイディオムですか?これを私に明確にしてくれてありがとう。

+2

なぜボードをmovePieceDownに渡していますか? –

+0

ええ、良いコール、それについてはごめんなさい、私は投稿のためのコードをサンプリングしていたときにタイプミスでした。今編集します。 – h00s

答えて

8

これは悪い方法ではありません。さまざまな方法にthisを渡すことは、プログラミングでは珍しいことではありません。それはちょうどあなたのデザインに依存し、私が心配している限り、Pieceクラスには何もありません。

Boardクラスの1つのことは、混乱するかもしれません - movePieceDownメソッド。使用できないパラメータBoard boardがあります。引数としてthisを使用する予定の場合、ボードは潜在的な引数として他のボードを受け取るべきではなく、実際には他のボードが存在する可能性があることを認識すべきではないので、

最後に、PieceがメソッドパラメータとしてBoardのインターフェイスを確認し、その契約が決して変更されないことを確認できます。例えば、それはこれらのメソッドを持つことができます:

public interface IBoard { 
    public boolean isFieldFree(int x, int y) 
    public Piece getPiece(int x, int y) 
} 

をどんなにあなたが後でボードの実装をどのように変化するか、これはそう、あなたがBoardを変更すると、あなたのPieceコードを手直しする必要はありません、常に動作するはずのものではありません。この方法で、Pieceがボードの状態を変更できないというルールを適用することができます(インターフェースでは、ボードの状態を変更するメソッドは公開しないでください)。

+0

あなたの答えdarijanと、クロアチアからの挨拶:)ありがとう。ええ、それは私のサンプルコードの誤植でした、そこにあることを意図していなかった、良い呼び出し。 – h00s

+0

助けになるのはうれしいです。 Nema na cemu。:) – darijan

2

私はそれが良い戦略だと思っています。特に、ローカル変数をメソッドに渡す必要があるときにはそうです。これらの地方の人々をすべて渡すのではなく、オブジェクトのインスタンスを渡すだけで、メソッドのシグネチャを整理できます。

このパラメータを受け取るメソッドがフィールドを変更したり、アクセスが制限されているメソッドを呼び出さないように、カプセル化を正しく練習してください。

3

まず、あなたの作品の変数がアンダースコアで終わるのはなぜですか?それは単なる奇妙なものです:p

あなたの質問は。私は、ピースクラス内での移動など、すべての関連するものを処理します。あなたがボード上のどの位置にいるかを知りたければ、xとyと呼ばれるピースクラスに2つの整数変数があります。

ピースは、ボード上の他のピースと衝突するかどうかを知る必要はありません。これは、ピースを動かすときにボードクラスが処理する必要があるためです。

たとえば、作品をx = 1、y = 2に移動すると、すでに位置1,2に作品があるかどうかをチェックし、それに応じて応答する必要があります。

「this」を別のクラスのメソッドに渡すのに間違いはありませんが、疎結合オブジェクト指向プログラミングの観点からは最適設計ではありません。

ちょうど私の2セント:)

+0

私のプライベートフィールドはすべてアンダースコアで終わっています:) Javaプログラミングスタイルガイドラインで指摘されているように、クラス変数とローカルスクラッチ変数を簡単に区別することができます。[リンク](http://geosoft.no/development/javastyle.html )あなたの2セントをありがとう:) – h00s

+0

@ h00sこれらの場合にアンダースコアを使用することはSunによって悪いスタイルと呼ばれます。私はオラクルが引き継いだことを知っていますが、それは古風なので、可能ならば避けるべきです。あなたの身長と幅もプライベートですが、方法によってアンダースコアで終わらないでください:) – JREN

+0

男、あなたは本当に物事を見逃すことはできません;)下線は私にはコンストラクタのようなものを公開します 'public color(color color){color_ = color ; } 'より明確に。それを 'public piece(カラーカラー){this.color = color; } '?それとも、Javaの最新のガイドラインがありますか?ありがとう! – h00s

2

は一般的に、thisを渡すことは珍しいことではありませんが、それは場合によって異なります。この場合の神は実装の詳細によって異なります。 Boardには、周りを動くことができるいくつかのパイプがあり、位置はピースの特性です。しかし、ある場所から別の場所に作品を移動することは、ボードの機能である可能性があります。たとえば、新しい場所が既に占有されている場合はどうなりますか?その後、作品は他の作品を周りに移動しますか?これはあなたの設計に適していますか?

あなたの署名の部分からは、moveTo関数がボードを受け入れることが期待されます。これは、あるボードが別のボードに移動できることを示しています。コードを読んでいるときには、本当にそうならない限り、これは誤解を招くかもしれません。

1

これを行うことでオブジェクト指向のプログラミングルールを制圧するかどうかはわかりませんが、Boardでメソッドを呼び出しているので、確かに奇妙に見えますが、このメソッドではメソッドを呼び出すしかありませんPieceをパラメータとして渡します。

オブジェクト指向プログラミングは、物事が現実世界のオブジェクトであるかのように見ていることについてたくさんあります。このアプローチに続いて、私はそれがボード上にあるかのように見ていきます。たとえば、ボードの位置はボード自体ではなく、ボードの位置によって決まります。このアプローチから、ピースを動かすことは、ピース自体ではなく、ボード上で行われることです。 Boardオブジェクトは、それの属性を認識していることから、その後、ほかにこのアプローチで

public class Board 
{ 
    private Piece p; 
    // ... 

    public boolean movePieceDown() 
    { 
     // Move the piece to a new location using it's setters 
    } 
} 

だから、パラメータとしてthisを渡すために間違っていないにもかかわらず、私はむしろメソッドを定義しますあなたが非常に多くのゲッターとセッターを呼び出す必要がなくなるため(例えば境界をチェックするため)、結果のコードははるかに読みやすくなります。

1

見出しの特定の質問に答えるだけで(OOデザインに関する一般的な意見ではありません):いいえ、悪い習慣ではなくむしろ一般的です。

ただし、コンシューマでthisを外部に渡すことは推奨されません。なぜなら、レシーバがソースが一貫性のない状態で表示される同時シナリオでは、厄介なバグにつながる可能性があるからです。

0

これは、通常のメソッド呼び出しで暗黙的に渡されます。このanswerを読んでくださいフォーラムに見つかりました。

JVM specificationも読むことができます。

関連する問題