2017-05-04 19 views
0

こんにちは私は複合パターンで作業しています。この最初のデザインパターンの例を使って説明します。https://github.com/bethrobson/Head-First-Design-Patterns/tree/master/src/headfirst/designpatterns/composite/menuiterator複合パターン、多型を自動入力する方法は?

すべてのメニューとサブメニューには、識別するIDが10文字であるとします。 この

0100000000 menu_1 
0101000000 menu_1's subMenu_1 
0102000000 menu_1's subMenu_2 
0102010000  subMenu_2's subMenu_3 
0200000000 menu_2 

のようなものと、私はランダムに持っていることは、メニュー項目があるが、それは、それが属するメニューIDでIDを持っています。例えば

0101000000 menuItem_1 
0200000000 menuItem_2 

だからMenuItemの1メニュー1のサブメニュー1に属し、MenuItemの2は、メニュー2.

それは次のようにコード化されるだろうに属します。

menu_1.add(subMenu_1); 
    subMenu_1.add(menuItem_1); 

menu_2.add(menuItem_2); 

ここでメニューをどのように埋めますか?

私がMenuItemsだけを取得しているために何をしているのか、私はIDがそれが所属する場所を特定するためにカットしています。 たとえば、メニュー1(0100000000)とメニュー2(0200000000)という2つのメニューがあるので、最初の2つの文字列を切り捨てる必要があります。

私はこのようにコーディングしています:

class AllMenus implements MenuComponent { 

    MenuComponent menu_1 
    MenuComponent subMenu_1 
    MenuComponent subMenu_2 
    MenuComponent subMenu_3 
    MenuComponent menu_2 

    @Override 
    add(MenuComponent menu) { 

     if(menu instanceof Menu) { 

     super.add(menu) 

     } else if(menu instanceof MenuItem) { 

     String subId = menuItem.getId().subString(0,2) 

     if(subId.equals("01")) { 

      if(menu_1 == null) { 
       menu_1 = new Menu(); 
       add(menu_1); 
      } 

      subId = menuItem.getId().subString(0,4); 

      if(subId.equals("0101")) { 

       if(subMenu_1 == null) { 
        subMenu_1 = new Menu(); 
        menu_1.add(subMenu_1); 
       } 
       subMenu_1.add(menuItem); 

      } else if(subId.equals("0102")) { 

       if(subMenu_2 == null) { 
        subMenu_2 = new Menu(); 
        menu_1.add(subMenu_2); 
       } 

       subId = menuItem.getId().subString(0,6); 

       if(subId.equals("010201")) { 

        if(subMenu_3 == null) { 

        subMenu_3 = new Menu(); 
        subMenu_2.add(subMenu_3); 

        } 
        subMenu_3.add(menuItem); 
       } 

      } 


     } else if(subId.equals("02") { 

      if(menu_2 == null) { 

       menu_2 = new Menu(); 
       add(menu_2); 
      } 
      menu_2.add(menuItem); 
     } 
     } 
    } 
} 

これは私が得るすべてのMenuItemのためのものです。ですから、このコードは長い間、4つのメニューのために見ることができますが、何千ものメニューを想像してください。 私は多型を繰り返すものに使うべきだと読んだことがありますが、私はこの場合どのようにしているのか分かりません。

+0

大文字で始まる変数名を指定すると、Javaの人が本当に混乱します。 'NamesStartingWithACapital'はクラス名のために予約されています。これを修正することをお勧めします。頭痛を冒さずにコードを見ることができれば、答えを得る可能性が高くなります。 – slim

+0

また、10桁の数字がどのように解釈されるべきかをさらに詳しく説明できますか?私はパターンが見えないと確信しています。 – slim

+0

@slimこんにちはパターンは、私はadd()メソッドを使用しています。その背後には反復子があり、MenuItemとMenuはMenuComponentを実装しています。十桁数字はmenuItemが属する場所です。メニュー項目は定数ですが、メニュー項目ではありませんが、subStringを使用してどこに属しているかを判断するためにmenuItemをいくつかのmenu.edited変数に追加する必要がある方法を判断してください – MarioK17

答えて

0

私があなたの質問を正しく理解していれば、あなたのコードに最終的な構造があまりにも多いと仮定していると思います。

一般に、コード内の数字リテラルは疑念を持って処理する必要があります。

if(subId.equals("010201") 

...コードではなく設定のように見えます。もちろん、あなたのコードに "設定"を入れることはいいですし、その設定がXML/CSV/JSON/etcではなくプログラムコードになることが実用的です。しかし、それでも "config"クラスと "code"クラスを論理的に分離することは良いことです。たとえば、あなたの「設定」クラスは、文字列の配列を返すメソッドを単に含まれる場合があります。

public class MenuConfig() { 
    public String[][] configs() { 
     return new String[][] { 
      new String[] {"0100000000", "Main menu"}, 
      new String[] {"0101000000", "Settings"}, 
      new String[] {"0101010000", "Look and feel"}, 
      new String[] {"0102000000", "My account"}, 
      // etc. 
     } 
    } 
} 

あなたがサブメニューのツリーを作成するために探している - 木(例えばバイナリツリー)を操作するためのコードにインスピレーションを探してください - コードがどれほどシンプルであり、各ノードに0個以上のサブノードがあるという事実を超えて、どのように仮定しないかを見てください。

あなたは既に多型を使用しています - あなたのメニューとサブメニューは共通の型に準拠しています(私はあなたのコードから同じ具体的な型を持つかどうかは分かりませんが、原則として、 MenuComponentを実装するクラスです。

1つのメニューを処理するために、あなたのコードはちょうどそれは行くし、それを挿入する必要がある場所を見つけ、その後、行くことになっていますどこ動作するようにIDを解析する必要があります。

(私はIDを提示していますあなたが01-02-01-00-00前​​を取り扱っている必要があります、またはあなたはNULLポインタを取得します - それは読みやすくするためハイフン)

// split "01-02-03-00-00" into [1,2,3] -- ignoring trailing zeros 
List<Integer> path = parse(currentMenu.getId()); 

MenuComponent m = rootMenuComponent; 
while(path.size() > 1) { 
    m = m.getSubMenu(path.remove(0)); 
} 
m.add(path.remove(0), currentMenu()); 

この単純なアルゴリズムでは、メニューが正しい順序で追加されていることを前提としています。

この制約を満たすことができない場合は、何が起こるかを定義し、その処理方法を決定する必要があります。

  • 実際にあなたの現在のスキームで、アルファベット順にキーをソートすると、彼らはアウトオブオーダーに来るつもりなら、あなたが追加するメニューののto-doリストを扱うことができ
  • 十分なものでなければなりませんキューとして。特定のアイテムをまだ追加できない場合は、そのアイテムをキューの背面に置き、残りのアイテムを処理した後に再試行します。
  • 中間メニューを明示的に定義する必要がないようにするには、m.getSubMenu(subMenuNum)null(暗黙的にパスの中央に定義されているため)を返した場合は、そのメニューで欠落したメニューを作成する必要がありますポイント。
  • 同じメニューを複数回定義することができるようにするには(暗黙的にも明示的にも)、MenuComponent.add()がマージまたは上書きのいずれかの要件を満たす必要があります。

このようなノードのグラフをアセンブルすることは、依存関係が任意の順序で定義されている場合に、グラフを順番に構築する処理です。あなたの目標が勉強であれば、自分のものを作り続けてください。メニューのコンポジットを作成したいだけなら、Spring(またはその他のDIフレームワーク)の使用を検討してください。

関連する問題