Java桌面应用MVC模式中控制器与模型的初始化及全局访问方案
Java桌面应用MVC的模型/控制器便捷访问方案
硬编码传递的优劣势
- 可行但不推荐:短期小项目里硬编码传递参数能快速实现,但随着模型/控制器数量增加,你需要不断修改
init方法的参数列表,子组件也要跟着修改接收参数,代码会变得臃肿且维护成本极高,新增组件时容易漏传或错传。
替代方案(类比React Redux/Vue Vuex)
1. 自定义全局上下文容器(轻量实现)
自己写一个单例的全局容器,把所有初始化好的模型和控制器存进去,视图组件直接从容器中获取,不用层层传递参数,类似Web里的全局store:
// 全局上下文类 public class AppContext { private static AppContext instance; // 存放所有模型和控制器 private ActionsModel actionsModel; private ActionsController actionsController; // 其他模型/控制器... private AppContext() {} public static AppContext getInstance() { if (instance == null) { instance = new AppContext(); } return instance; } // 初始化方法,在Main中调用 public void init() { actionsModel = new ActionsModel(); actionsController = new ActionsController(); // 初始化其他模型/控制器... } // 提供getter方法 public ActionsModel getActionsModel() { return actionsModel; } public ActionsController getActionsController() { return actionsController; } // 其他getter... }
修改Main类:
public class Main { public static void main(String[] args) { // 初始化全局上下文 AppContext appContext = AppContext.getInstance(); appContext.init(); MainWindow viewMainWindow = new MainWindow(); viewMainWindow.init(); // 无需传递一堆参数 } }
视图组件中直接使用:
public class MainWindow { public void init() { ActionsModel model = AppContext.getInstance().getActionsModel(); ActionsController controller = AppContext.getInstance().getActionsController(); // 业务逻辑处理 } }
2. 依赖注入框架(适合中大型项目)
类似Web框架的插件注册,Java里可以用Spring或Guice这类DI框架,把模型和控制器注册为单例Bean,视图组件通过注解自动注入,不用手动管理实例和传递:
以Spring为例,先配置Bean:
@Configuration public class AppConfig { @Bean public ActionsModel actionsModel() { return new ActionsModel(); } @Bean public ActionsController actionsController() { return new ActionsController(); } // 其他Bean配置... }
Main类初始化Spring上下文:
public class Main { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); MainWindow viewMainWindow = context.getBean(MainWindow.class); viewMainWindow.init(); } }
视图组件中通过@Autowired注入:
public class MainWindow { @Autowired private ActionsModel actionsModel; @Autowired private ActionsController actionsController; public void init() { // 直接使用注入的模型和控制器 } }
3. 封装组合对象(折中方案)
如果不想用框架也不想搞全局单例,可以把所有模型和控制器封装到一个统一的上下文对象中,只传递这个对象给视图,避免多参数传递:
// 组合上下文类 public class AppServices { private final ActionsModel actionsModel; private final ActionsController actionsController; // 其他模型/控制器... public AppServices() { this.actionsModel = new ActionsModel(); this.actionsController = new ActionsController(); // 初始化其他组件... } // getter方法 public ActionsModel getActionsModel() { return actionsModel; } public ActionsController getActionsController() { return actionsController; } }
Main类中使用:
public class Main { public static void main(String[] args) { AppServices appServices = new AppServices(); MainWindow viewMainWindow = new MainWindow(); viewMainWindow.init(appServices); // 只传一个参数 } }
视图组件中获取:
public class MainWindow { private AppServices appServices; public void init(AppServices appServices) { this.appServices = appServices; ActionsModel model = appServices.getActionsModel(); // 业务逻辑处理 } }
内容的提问来源于stack exchange,提问作者AlexV
相关产品推荐
相关产品推荐

