2016-11-07 63 views
2

在這裏,我正在構建帶有n個葉和分支的菜單生成器,現在我無法正確返回構建器的引用而無法解決問題。嵌套的菜單生成器永遠不會在c中正確結束#

這裏是代碼

public interface IMenuBuilder 
{ 
    IMenuBuilder AddLeaf(string name); 
    ISubMenuBuilder AddBranch(string name); 
    void Build(); 
} 

public interface ISubMenuBuilder : IMenuBuilder 
{ 
    ISubMenuBuilder AddLeaf(string name); 
    INestSubMenuBuilder AddBranch(string name); 
    IMenuBuilder Build(); 
} 

public interface INestSubMenuBuilder : ISubMenuBuilder 
{ 
    INestSubMenuBuilder AddLeaf(string name); 
    INestSubMenuBuilder AddBranch(string name); 
    ISubMenuBuilder Build(); 
} 

public class MenuBuilder : IMenuBuilder 
{ 
    List<Menu> menus = new List<Menu>(); 
    public IMenuBuilder AddLeaf(string name) 
    { 
     var menu = new RootMenu { Name = name }; 
     menus.Add(menu); 
     return this; 
    } 

    public ISubMenuBuilder AddBranch(string name) 
    { 
     var menu = new RootMenu { Name = name }; 
     menus.Add(menu); 
     return new SubMenuBuilder(this, menu); 
    } 

    public void Build() 
    { 
    } 
} 

public class SubMenuBuilder : ISubMenuBuilder 
{ 
    private IMenuBuilder menuBuilder; 
    private ISubMenuHolder menu; 

    public SubMenuBuilder(IMenuBuilder menuBuilder, ISubMenuHolder menu) 
    { 
     this.menuBuilder = menuBuilder; 
     this.menu = menu; 
    } 

    protected SubMenuBuilder(ISubMenuHolder menu) 
    { 
     this.menu = menu; 
    } 

    public ISubMenuBuilder AddLeaf(string name) 
    { 
     var leafMenu = new LeafMenu { Name = name }; 
     leafMenu.ParentId = (leafMenu as Menu).Id; 
     menu.AddSubMenu(leafMenu); 
     return this; 
    } 

    public INestSubMenuBuilder AddBranch(string name) 
    { 
     var branchMenu = new BranchMenu { Name = name }; 
     branchMenu.ParentId = (branchMenu as Menu).Id; 
     menu.AddSubMenu(branchMenu); 
     return new NestSubMenuBuilder(this, branchMenu); 
    } 

    public IMenuBuilder Build() 
    { 
     return menuBuilder; 
    } 


    IMenuBuilder IMenuBuilder.AddLeaf(string name) 
    { 
     this.AddLeaf(name); 
     return this; 
    } 

    ISubMenuBuilder IMenuBuilder.AddBranch(string name) 
    { 
     this.AddBranch(name); 
     return this; 
    } 

    void IMenuBuilder.Build() 
    { 
    } 
} 

public class NestSubMenuBuilder : INestSubMenuBuilder 
{ 
    private ISubMenuBuilder subMenuBuilder; 
    private ISubMenuHolder branchMenu; 

    public NestSubMenuBuilder(ISubMenuBuilder subMenuBuilder, ISubMenuHolder branchMenu) 
    { 
     this.subMenuBuilder = subMenuBuilder; 
     this.branchMenu = branchMenu; 
    } 

    public INestSubMenuBuilder AddLeaf(string name) 
    { 
     var leafMenu = new LeafMenu { Name = name }; 
     leafMenu.ParentId = (leafMenu as Menu).Id; 
     branchMenu.AddSubMenu(leafMenu); 
     return this; 
    } 

    public ISubMenuBuilder Build() 
    { 
     return subMenuBuilder; 
    } 

    public INestSubMenuBuilder AddBranch(string name) 
    { 
     var menu = new BranchMenu { Name = name }; 
     menu.ParentId = (branchMenu as Menu).Id; 
     branchMenu.AddSubMenu(menu); 
     return new NestSubMenuBuilder(this, menu); 
    } 

    ISubMenuBuilder ISubMenuBuilder.AddLeaf(string name) 
    { 
     this.AddLeaf(name); 
     return this; 
    } 

    IMenuBuilder ISubMenuBuilder.Build() 
    { 
     return subMenuBuilder; 
    } 

    IMenuBuilder IMenuBuilder.AddLeaf(string name) 
    { 
     this.AddLeaf(name); 
     return this; 
    } 

    ISubMenuBuilder IMenuBuilder.AddBranch(string name) 
    { 
     this.AddBranch(name); 
     return this; 
    } 

    void IMenuBuilder.Build() 
    { 
    } 
} 

這是我的建設者的代碼和這裏是我在使用該API構建了問題的例子。

 builder 
       .AddLeaf("Leaf 4") 
       .AddBranch("Branch 2") // subMenuBuilder 
        .AddLeaf("Branch 2 -> Leaf 1") 
        .AddBranch("Branch 2 -> Branch 1") //nestSubMenuBuilder 1 
          .AddLeaf("Branch 2 -> Branch 1 -> Leaf 3") 
          .AddBranch("Branch 2 -> Branch 1 -> Branch 1") //nestSubMenuBuilder 2 
           .AddLeaf("Branch 2 -> Branch 1 -> Branch 1 -> Leaf 1") 
           .Build() // nestSubMenuBuilder 1 
          .AddLeaf("Branch 2 -> Leaf 4") 
          .Build() // subMenuBuilder 
        .AddLeaf("Branch 2 -> Leaf 2") 
        .Build();// menubuilder 

這裏我沒有得到最後的菜單生成器引用回來添加新的葉子和分支。

+0

IM沒能獲得最後的構建初始菜單生成參考方法。 –

+0

與添加的'void Build()'方法不一樣的問題?你使用的是什麼API(有沒有與它相關的標籤或某個文檔API?)或者這更像是一個代碼評論問題?我真的不明白爲什麼最初的'IMenuBuilder'不是你界面中所有'Build'方法的所有者,以及爲什麼你要讓子接口覆蓋它們。重寫的子接口不應該改變構建方法,它應該返回簡單地返回所有情況下的'IMenuBuilder' – Icepickle

+0

「現在我無能爲力了......」我很難破解:D –

回答

1

您的問題是,您的代碼爲每個菜單級別返回不同的構建器對象。相反,你應該總是返回相同類型的建設者,並達到了頂級水準的時候,剛剛從Build()返回null

建議Builder代碼:

public interface IMenuBuilder 
{ 
    IMenuBuilder AddLeaf(string name); 
    IMenuBuilder AddBranch(string name); 
    IMenuBuilder Build(); 
} 

public class MenuBuilder : IMenuBuilder 
{ 
    private IMenuBuilder menuBuilder; 
    private ISubMenuHolder menu; 

    /// <summary> 
    /// Create a new menu with specified root item 
    /// </summary> 
    public MenuBuilder(string rootName) 
    { 
     this.menuBuilder = null; 
     this.menu = new RootMenu { Name = rootName }; 
    } 

    /// <summary> 
    /// Create a new sub menu with specified parents 
    /// </summary> 
    public MenuBuilder(IMenuBuilder parentBuilder, ISubMenuHolder menu) 
    { 
     this.menuBuilder = parentBuilder; 
     this.menu = menu; 
    } 

    public IMenuBuilder AddLeaf(string name) 
    { 
     var leafMenu = new LeafMenu { Name = name }; 
     leafMenu.ParentId = menu.Id; 
     menu.AddSubMenu(leafMenu); 
     return this; 
    } 

    public IMenuBuilder AddBranch(string name) 
    { 
     var branchMenu = new BranchMenu { Name = name }; 
     branchMenu.ParentId = menu.Id; 
     menu.AddSubMenu(branchMenu); 
     return new MenuBuilder(this, branchMenu); 
    } 

    public IMenuBuilder Build() 
    { 
     return menuBuilder; 
    } 
} 
+0

謝謝,我使用完全相同的做法。 –

相關問題