我正在构建一个小型控制台应用程序,作为刷新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。
解决这个问题的好方法是什么?
答案 0 :(得分:2)
您可能希望将依赖注入视为一种解决方案。它非常适合管理 在这种情况下服务依赖。有一些很好的独立DI实现,如Guice,Weld和PicoContainer。
答案 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
}
}
我希望它能解决你的问题:)