2011-12-21 16 views
3

私は、特定のOOP問題の構成について簡単に質問します。OOP組織の問題に最適な解決策

私にはタイルズでいっぱいの地形クラスがあります。クラスタイルの複数の派生物、すなわちドアがあります。 Doorクラスには、open()というメソッドがあり、これはドアを開き、close()はドアを閉じます。これは、これらの方法の両方が、開封および/または閉封の前に途中で何かを点検する必要があるまで完全な意味を持ちます。どのようにして、その親について知らないうちにオブジェクトのDoorチェックを行うのですか?

open()を呼び出す前に、途中で何かをチェックするのが簡単な解決策ですが、別の種類のドアをチェックする必要があるドアの種類が異なると、より高いレベルで混乱が生じます。

これは簡単な答えがあるようですが、私はこの問題をより頻繁に実行するように思われます。

+3

ドアは非アクティブで、ハンドラが開閉し、ドアがブロック/ロックされているかどうかをチェックする必要のあるハンドラです。ドアはそれ自体について知っているだけで、環境の中の他のものについては知りません。 – slashmais

+0

@slashmaisだから私のソリューションは正しいですか? – lowq

+0

はい、正しく見えます - それぞれのハンドラはドアに近づく方法がそれぞれ異なるでしょう。例:ドアを開けたり開けたりすると、警官が蹴ってきます。自動化された装置がそれをやります。 – slashmais

答えて

2

1つの答えは、ドアは自分自身を開いたり閉じたりする方法を知っていて、ブロックされているかどうかを知る必要があります。ドアがクラスである場合、状態の両方が( IS_OPENをis_blocked)と行動( open_the_door close_the_door)はドアクラスに存在するべきです。カプセル化は、オブジェクト指向のパラダイムの基本原則です。

しかし、現実の答えは、通常、より微妙です。アプリケーションの背景と達成するために必要なことを教えてください。おもちゃのアプリケーションではうまくいく、クリーンでシンプルなソリューションがありますが、アプリのサイズが大きくなると、より洗練されたものが必要になります。

ドアの取り扱い方法 is_blockedにはいくつかの設計上の問題があります。正しいデザインはありませんが、良いデザインと悪いデザインがあります。良いアイデアと悪いアイデアを分けることは、デザインの原則だけでなく、問題の文脈にもよります。

私が推測しなければならないのは、あなたのアプリケーションがゲームだと思います。タイルは、ゲームボードやマップの領域を表しているかもしれません。あなたは、多くの異なるオブジェクトが相互作用しなければならない可能性があることを認識しており、相互に直接参照している場合は混乱することになります。

  • ゲームには、「ゲーム」または「ボード」または「マップ」と呼ばれるマスターオブジェクトがあることがよくあります。マスターオブジェクトにタイル階層(タイル、ドアなど)内のもののコレクションを保持させます。

  • また、マスターオブジェクトには、ドアをブロックしたり、タイルやドアと相互作用したりすることができるもののコレクションを保持させます。

  • これで、オブジェクトをパラメータとして受け入れるTileクラスにupdate()という名前のメソッドを作成しました。

  • そして、 "blocked"というDoorクラスのブール値属性を作成します。 Doorの更新方法は、

    Door::update(BlockingObject object) { 
    if(object.location == this.location) 
         blocked = true 
    }

  • The method on the superclass of door might do nothing. Like this:

    Tile::update(BlockingObject obj) { 
        //tiles cannot be blocked 
    }

  • Now, inside the game loop, include a step where all the doors are set to blocked = falseのようになります。

  • いくつかのループを作成すると、すべてのタイルがブロックされているかどうかを確認するよう求められます。これは、擬似コードで次のようになります。

    For each tile { 
        For each blocking object { 
          tile.update(object) 
        } 
    }

  • これは、オブジェクト指向のパラダイムにも当てはまるナイーブが、まっすぐなデザインです。

  • このデザインは、タイル/ドアとオブジェクトに、1回に1回、相互参照を強制することなく、1回の交信の機会を与えます。

  • このデザインは、数百のタイルやオブジェクトでうまく動作しますが、何千ものタイルでは非常に遅くなります。

良いデザインですか?

答えはアプリケーションのニーズによって異なります。

+0

はい。それは間違いなくゲームです。私はあなたの解決策が気に入っていますが、 'update(BlockingObject)'はドアにのみ存在する関数のように思えます。他のタイルには適用しないでください。 速度のためにタイルが追加または削除されたときに、周囲のタイルを更新することしか表示されませんでした。 – lowq

関連する問題