web-dev-qa-db-ja.com

新しいオプションを簡単に追加できるように、Javaベースのメニューを設計する

Javaいくつかのオプションを含むメニューを表示するコンソールプログラムを作成しようとしています。各オプションを選択すると、スクリプトの実行やdb操作の実行など、いくつかの独立した操作が実行されます。次に例を示します。

1 option1title  
2 option2title  
3 option3title  
...  

新しいオプションを簡単に追加できるように設計する必要があります。新しいクラスを追加するだけで言います。一部のオプションでは、サブメニューも表示される場合があります。

私が持っているデザインの考え

IOptionoptionTitleのようなメソッドを使用して、インターフェースにoptionActionと伝えます。したがって、メニューの各Optionはこのインターフェースを実装し、そのアクションとタイトルを記述します。

メニューを表示するにはどうすればよいですか?
各オプションが登録されているクラスを持つことができます。すべてのオプションのリストを言います。次に、私のメインプログラムはこのクラスを反復処理し、メニューを表示します。オプションを選択すると、その特定のクラスのアクションが呼び出されます。
それ以外の場合は、リフレクション/アノテーションを使用して、このインターフェイスを実装するすべてのクラスを取得し、メニューを表示できます---->これはやり過ぎかもしれません。

これを設計するためのより良い方法はありますか?持ち込めるデザインパターンはありますか?私の優先事項は良いデザインです。

私のソリューションでも、新しいオプションを追加したい場合は、各オプションをリストに登録したり、クラスを実装したりする必要があります。
レジスタクラスのリストに追加する代わりに、optionTitleとxmlファイルなどのクラス情報との間にリンクを設定するのはどうですか?

また、サブメニューもあります。これをitemActionメソッドで記述する以外に、これを設計するためのより良い方法はありますか?

さらに情報を追加する必要がある場合はお知らせください。
注:これは常にコマンドプロンプトから呼び出されます。シェル/ウィンドウコマンドプロンプトのいずれか。これにはGUIは必要ありません。

1
Manu Mathew

提案されたデザイン:

コマンドパターン を使用できます:

  • コマンドインターフェイスは、メニューオプション(つまりコマンド)に関連するメソッドを定義します。ここで最も重要なメソッドはoptionAction()です(パターンのexecute()メソッドに対応します)。
  • 具体的なコマンドは、このインターフェイスを実装するクラスです。optionAction()は、特定のコマンドに対して実行されるアクションを定義するためにオーバーライドされます。
  • 具体的なコマンドがクライアントによってインスタンス化されると(main()?)、レシーバーオブジェクトへの参照が保存されます。そのオブジェクトは、後でアクションを実行するために使用されます。
  • 特定の具象コマンドクラスは、アクションとしてメニューループを実装します。ただし、独自のクラス内のすべての異なるサブメニューをハードコーディングする代わりに、単一のSubmenuCommandクラスを使用します。そのインスタンスは、オプション(コマンド)のリストを持つメニューオブジェクトを参照します。
  • 呼び出し元は、必要に応じて作成されたコマンドを実行します。あなたの場合、あなたは呼び出し元を単純化することができます:あなたのmain()はどういうわけかトップレベルメニューに対応するコマンドを呼び出すでしょう。そして、これは選択されたコマンドを呼び出します。

このデザインのバリエーション:

メニューオブジェクトは、初期化中に作成できます。通常、プログラムで各メニューを初期化するには、 ビルダーパターン を使用します。次に、optionTitle()を使用することが理にかなっています。

ただし、構成ファイルからメニューをロードすることもできます。この場合、optionTitle()は役に立ちません。構成ファイルからそのタイトルを読み取ります(テキストをカスタマイズする柔軟性があり、メニューをローカライズ/翻訳することもできます)。原則として、ビルダーのディレクターでそれを行いますが、他のコマンドも構成したい場合は、 factory method pattern も検討できます。

メニューを動的にロードすることを選択した場合、処理すべき微妙な点がいくつかあります。

  • まず、メニューのテキストをコマンドクラスにリンクする必要があります。リフレクションを使用して適切なクラスを名前で識別するか、または-より簡単に-コマンドに対応するキーワードをクラス固有のファクトリーにリンクするマップを使用します(マップは静的であり、構成ファイルが解析される前に初期化されます)。
  • メニュー間の依存関係:最も簡単な方法は、メニューを下から上に整理することです。そのため、メニューが他のメニューで参照される前に、常にロード/作成されるようにします。コマンドクラスと同様に、メニューのマップもあります(マップは動的であり、新しいメニューが読み込まれると入力されます。したがって、メニュー構造は完全に動的で再構成可能です)。

まとめ:

ここでは、一般的な構造を示す簡略化されたクラスモデルを示します。ただし、クライアント、呼び出し側、ディレクター、およびビルダーは、アプリケーションの残りの部分に大きく依存するため、この図から除外します。

enter image description here

3
Christophe