Java - 通过多个层传递变量的替代方法

时间:2013-01-23 06:08:03

标签: java interface

我正在构建一个小型控制台应用程序,作为刷新Java的练习(去年经过一年的Java后一直在做Haskell和Scala)。我有以下界面建模菜单行为:

public interface MenuItem {
    public String output();
    public InputHandler requestInput();

public interface InputHandler {
    public String promptUser();
    public MenuItem handleInput(String input);
}

使用类似的一些示例实现:

public class MainMenu implements MenuItem {

    public String output() {
        return "1.) Browse Books\n" +
               "2.) View membership details\n" +
               "3.) Exit\n";
    }

    public InputHandler requestInput() {
        return new InputHandler() {
            public String promptUser() {
                return "Please select an option:\n";
            }

            public MenuItem handleInput(String input) {
                int menuItem = Integer.parseInt(input);
                if (menuItem == 1) {
                    return new BrowseBooks();
                } else if (menuItem == 2) {
                    return new ViewUserDetails();
                } else {
                    return new MainMenu();
                }
            }
        };
    }
}

我的问题是这些MenuItem实现类的 SOME (例如BrowseBooksMenu)需要访问其他类(即说一个处理借书的LibraryManager类) 。我不能只将这个LibraryManager类传递给BrowseBooks类,因为它还需要传递到MainMenu类(因为它们是圆形的),因而成为一个对于仅在特定MenuItem中使用的实例的大型构造函数的大型shitstorm。

解决这个问题的好方法是什么?

3 个答案:

答案 0 :(得分:2)

您可能希望将依赖注入视为一种解决方案。它非常适合管理 在这种情况下服务依赖。有一些很好的独立DI实现,如GuiceWeldPicoContainer

答案 1 :(得分:1)

  

我不能将这个LibraryManager类传递给BrowseBooks类,因为它还需要传递到MainMenu类(因为它们有点循环)

这取决于构建此LibraryManager所需的内容。如果根本不需要,你可以简单地在BrowseBooks类中构造它。如果需要某些全局配置,您可以构建一个全局单例并将其存储在某个静态字段中。 Singleton Design Pattern in Java上的答案包含有关如何初始化单例的代码段,具体取决于您是希望早期还是懒惰地进行初始化。

如果您希望对管理员的来源保持灵活性,您可能需要查看dependency injection,可能需要使用Inversion of Control Container

答案 2 :(得分:0)

您只需使用设计模式即可解决,无需使用DI系统。

这是一个我认为适合你的快速代码原型,并删除了LybraryManager和其他类之间的依赖关系。

//LybraryManager singleton class
        public class LybraryManager{

    public static LybraryManager getInstance(){    //basic code for singleton pattern }

    public void addLybraryManagerListener(LMListener listener){    listneres.add(listener) }

    public void someLybraryOperation(){
         //iterate by the listeners and invoke the method
         listener.someLybraryOperationExecuted(someParam); }


    public interface LMListener{
         public void someLybraryOperationExecuted(Object someParam);
    }

//Class MainMenu that implement listener for lybrarymanager, and listen to operation
public class MainMenu implements LMListner {
    public MainMenu(){
        LybraryManager.getInstance.addLMListener(this);
}

public void someLybraryOperationExecuted(Object someParam){
    //do anything you need
}

}

我希望它能解决你的问题:)