1

我正在构建一个小型控制台应用程序作为复习 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 实现类(BrowseBooksMenu例如)需要访问其他类(即LibraryManager处理借书的类)。我不能只将这个LibraryManager类传递到BrowseBooks类中,因为它还需要传递到MainMenu类中(因为它们是循环的),因此对于仅在特定 MenuItems 中使用的实例而言,它会成为大型构造函数的大风暴。

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

4

3 回答 3

2

您可能希望将依赖注入作为解决方案。在这种情况下管理服务依赖关系非常有用。有几个很好的独立 DI 实现,例如GuiceWeldPicoContainer

于 2013-01-23T06:22:01.910 回答
1

我不能只将这个LibraryManager类传递给BrowseBooks类,因为它也需要传递给MainMenu类(因为它们是循环的)

这取决于构建 this 需要什么LibraryManager。如果什么都不需要,您可以简单地在BrowseBooks类中构造它。如果需要一些全局配置,您可以构建一个全局单例并将其存储在某个静态字段中。Java中的单例设计模式的答案有关于如何初始化单例的代码片段,具体取决于您是希望该初始化提前还是延迟进行。

如果您想灵活了解该管理器的来源,您可能需要查看依赖注入,可能使用一些Inversion of Control Container

于 2013-01-23T06:25:40.143 回答
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
}

}

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

于 2013-01-23T06:40:05.683 回答