1

さて、最近、Javaで「ペイントアプリケーション」を作成しました。MS Windows Paintに似た小さなプログラムで、明らかに(私のソースコードを評価した一部の人々によると)私のアプリケーションでクラスを適切に使用していません。残念ながら、何が間違っているのかわかりませんが、何が間違っているのかを教えてくれる人は誰もいません。

継承の概念を使用する「適切な」クラスがあります。

PaintObject  
-ClosedObject  
--RectangleShape  
--OvalShape  
-OpenObject  
--PointShape  
--LineShape  

しかし、それでも私はコードで何が間違っているのか、クラスが適切に使用されていないと考えることにつながる可能性があるのか​​わかりません...

(私の意見では)間違っている可能性があるのは、次のような新しいオブジェクトを作成して描画するという事実だけです。1つのフィールド変数(おそらくタイプ)new RectagleObject(...)new OvalShape(...)作成する代わりに、メソッドが呼び出されたときに適切な形状を割り当てます(明らかにその特定の形の描画と一緒に)objectToBeDrawnPaintObjectexecuteOperation

コードサンプルは次のとおりです。

public void executeOperation(Graphics2D gr, int oper, boolean drawingMode){
    if(oper==1){
        new RectangleShape(startLocation, endLocation, borderColor, fillColor).draw(gr);
    }
    else if(oper==2){
        new OvalShape(startLocation, endLocation, borderColor, fillColor).draw(gr);
    }
    ....//more operations
}

誰もが一般的なプログラミングの習慣に関して何が間違っている可能性があるかを知っています(私の「推測」が正しい場合を除きますか?-そうである場合は、私の疑問を確認してください)。それとも何か他のものがありますか?oper==1(そのような値は定数として定義されるべきであることがわかっているので 、の一部をスキップしてください)

私の経験は「限られている」(実際にはない)ので、どんな助けでも大いに感謝します。私は自分で学び、プロのプログラムがどのように設計されているか(そしてそのパターンに従うか)を推測するのは本当に難しいです。

4

4 に答える 4

3

ラスターイメージを描画している場合、ユーザーが描画しているものを追跡する必要がありますか?おそらく、、などのオブジェクトを意味しますPenToolRectangleTool

現在、特定の形状を描画するために永続化および再描画されるオブジェクトを作成しているようです。必要に応じて、ツールオブジェクトを一Image度だけ描画することができます(グラフィックスコンテキストをクリアしないでください)。activeToolツールが選択されたら、特定のツールを特定のフィールドに割り当てるだけです。

class DrawingTool {
     public void draw(Graphics g) { }
}

class PenTool extends DrawingTool {
     public void draw(Graphics g) {
         // some drawing logic
     }
}

class RectangleTool extends DrawingTool {
     public void draw(Graphics g) {
         // some other drawing logic
     }
}

だから代わりに

oper = 1;

あなたは書くだろう

activeTool = new PenTool(); // or activeTool = PenTool.GetInstance();

または同様のもの。何かを描きたいときは、drawメソッドを呼び出すだけです。前に述べたように、これは、Image決してクリアしないものを渡すだけで実行できます。

class DrawingCanvas {
     Image image = createImage(GetWidth(), GetHeight());
     DrawingTool activeTool;

     // this is what gets invoked on every frame
     public void paint(Graphics g){
          g.drawImage(image, 0, 0, null);
     }
}

// when you need to draw something
// (not on every frame, but something new)
activeTool.draw(image.getGraphics());
于 2012-07-12T18:32:55.293 に答える
3
if(oper==1){
    //...
}
else if(oper==2){
    //...
}

これは、オブジェクト指向プログラミングを適切に使用すれば、99% の確率で回避できるコードの種類です。整数が必要な理由を調べてください。operおそらく、その必要をなくすために変更できるパターンがあります。たとえば、現在、ツールバーの各ボタンに整数値を割り当てている場合は、代わりに、ボタン ハンドラーを、OperationFactoryそのボタンに関連付けられた型のオブジェクトを生成するものに現在の値に設定することができます。

于 2012-07-12T18:36:38.080 に答える
1

各タイプ (具体的には OvalShape と RectangleShape) は両方とも「executeOperation」メソッドを実装する必要があります。このメソッドは、基本クラス (閉じたオブジェクト) の「executeOperation」メソッドをオーバーライドする必要があります。

これにより、if(oper == 2)... else (oper == 2) の必要がなくなります。オブジェクトのタイプに関連する実装を呼び出すだけです。

于 2012-07-12T18:43:13.170 に答える
0

小さなスニペットから、おそらくポリモーフィズムをもっと活用することができます。たとえば、executeOperation(Graphics2D gr、boolean drawingMode)メソッドを定義する親の抽象クラス/インターフェイスがあり、サポートする操作ごとにそれを拡張/実装します(drawingmodeも削除できる可能性がありますが、何をするのかわかりません)。おそらく、graphics2Dもコンストラクターに入れます。

于 2012-07-12T18:33:36.490 に答える