关于可插拔Java框架的设计问题

关于可插拔Java框架的设计问题,java,plugins,frameworks,Java,Plugins,Frameworks,在过去的4年里,我在业余时间做了一个项目,目标有两个:作为一名软件工程师提高自己,以及构建(我希望)能够帮助我构建更快更好的Java应用程序的东西。我一直喜欢模块化的应用程序,所以我觉得有一个可插拔的框架也不错 因为我总是在构建东西之前先看(不需要重新发明轮子,对吗?),所以我在看Eclipse和NetBeans,但缺少了一些东西,它没有我想要的东西: Eclipse和NetBeans是客户端应用程序的优秀平台,是很好的插件系统,但是如何基于插件编写服务器端应用程序呢?客户端/服务器可插拔应用

在过去的4年里,我在业余时间做了一个项目,目标有两个:作为一名软件工程师提高自己,以及构建(我希望)能够帮助我构建更快更好的Java应用程序的东西。我一直喜欢模块化的应用程序,所以我觉得有一个可插拔的框架也不错

因为我总是在构建东西之前先看(不需要重新发明轮子,对吗?),所以我在看Eclipse和NetBeans,但缺少了一些东西,它没有我想要的东西:

  • Eclipse和NetBeans是客户端应用程序的优秀平台,是很好的插件系统,但是如何基于插件编写服务器端应用程序呢?客户端/服务器可插拔应用程序如何
  • 如果您只想编写一个小应用程序,那么就有点重了;另外,像Swing应用程序框架这样的东西对我来说太简单了(我不是在批评,这是编写Swing应用程序的一个很好的起点——它有一个小而简单的API)
  • 不适合使用相同的API构建客户端、服务器端或客户端/服务器应用程序(双方的API并不完全相同,而是更统一的API)
当然,在这几年中,该框架经历了几个重大里程碑,在几个项目中使用过,并且达到了它的目的(或多或少)。API改变了以满足一些需求,但我对当时看起来不错的一些设计决策不满意。此外,还有一些事情困扰着我,这就是我的问题的来源。这么多年后,我为什么要问这些问题?好问题:),可能是因为现在我想把它公之于众,在我这么做之前,我想澄清一些事情(或者可能以前没有像StackOverflow这样的网站:)

首先,让我非常简洁地解释一下它提供了什么:

  • 基于插件的模块化设计
  • 应用程序功能由服务提供,不同的插件创建和注册服务,这些服务提供特定的功能:模板、持久性、调度、作业/任务执行、安全性、自动更新等
  • 应用程序在XML文件中描述,每个应用程序在多个模块中结构化,每个模块包含1..N个插件;插件在模块之间共享(基本上,一小部分插件创建应用程序核心,其余插件可以以某些方式区分应用程序,如不同的应用程序UI。当然,这仅对客户端有意义,在服务器端,所有插件都被实例化以提供对任何客户端类型的支持)
  • 每个插件都加载在自己的类加载器中,并且有一个应用程序生命周期:加载插件、初始化插件(此时所有服务都已注册)、初始化服务、后初始化服务、后初始化插件、后初始化UI插件、后初始化UI插件、启动插件
  • 每个插件都有自己的XML描述符文件来添加/注册/配置应用程序,有一个API允许通过XML轻松配置应用程序,类似于Apache Commons Digester
  • 插件是从几个应用程序存储库加载的,与Maven解析依赖项的方式相同;还支持Maven 1和2存储库
  • 5-10行内的自动应用程序部署(Ant任务)(基本上是2-3行-任务定义和调用-但有一些设置涉及如何更改应用程序布局-插件、库、引导库、应用程序启动脚本、应用程序数据等的放置位置)
下面是问题:

1a)以前的版本是基于应用程序应该只有一个小的代码库的思想构建的:引导库(用于基本的应用程序支持)和应用程序API(框架API+应用程序API/API)。插件之间没有可见性,每个插件只需导入几个jar文件。这似乎是一件很好的事情,将开发人员从jar/类的地狱中释放出来,类似于代码隔离,您只看到您需要看到的东西。这也有一些缺点,测试不是真正的单元测试,更像是一个集成测试,因为您只看到“公共”API,然后开始整个测试,然后查询模块整体是否工作良好。在某些情况下,类加载也存在一些问题(问题已解决,但…)

b) 由于单元测试是主要问题,当前版本改变了加载所有内容的方式:确切地说,与任何常规应用程序一样,您必须导入所需的每个jar—当然,这些jar也会在运行时动态加载。类加载已更改,因此在测试时加载插件/库的方式与运行时没有区别,您可以访问所有导入的插件/库中可用的每个公共实现。最后,即使代码更易于测试,我还是以编写更像集成测试而不是单元测试而告终,因为(我很懒)框架在为我提供已经实例化的服务而不是提供大量存根/模拟时更方便。问题是我失去了我以前拥有的东西,在开发过程中只有一个小的可见代码库的简单性

问题:需要更好的单元测试是否比某种简单性更有价值(当然,在这种情况下)?这真的是“更好”,或者我只是习惯了更好的想法,拥有更多的可测试代码(或者至少有机会编写更多的可测试代码)意味着放弃其他一切?

2我发现有一件事很有用,那就是让应用程序实例在连接到当前线程的任何时候都可用。由于框架控制所有线程(不需要创建线程,只需创建一个辅助线程并对其进行调度)以及所有线程