最近接手一个系统的维护工作,发现该系统的现状有些奇怪:
该系统是一个B/S系统。大家知道一般这种应用就是对应一个工程,工程的目录符合规范,比如在WEB-INF下的lib包里放依赖的jar包等。然后这个工程可以直接打成war包,放到servlet容器里就可以跑起来
但是这个系统不是这样的,它是由30多个工程组成的。这些工程都不具备单独打包,单独跑起来的能力
比如每个工程都没有lib目录(有的工程甚至没有WEB-INF目录),所有工程依赖的jar包在工程外部统一管理(关键这些jar包不是静态的,比如说工程B依赖工程A打出的一个A.jar,而工程A也在时时更新中)
再比如说有的工程有web.xml,有的工程就没有web.xml,但是并不是所有的web.xml都是有用的,实际上后面会说到,只有一个web.xml起作用,其他的都是摆设
总的来说,就是有这么30多个工程。然后有一个用ant写的整体的编译脚本和部署脚本,首先需要运行一下编译脚本,把所有工程编译一遍,当然这个编译顺序是有讲究的,比如前面说过,工程B依赖工程A编译后生成的jar包,那就必须先编译工程A,再编译工程B,否则工程B就编译不通过
运行完编译脚本以后,再运行一下部署脚本,把.class文件、.jsp文件、资源文件、配置文件等一起打成一个war包
最后把这个war包扔到容器里,才能跑起来
这几天熟悉过程中,感觉比较痛苦,觉得至少有以下几个弊端:
1、最主要的问题,就是修改的代码没有办法马上验证。像一般的WEB工程,可以直接通过IDE(比如eclipse)发布到容器里,代码修改以后会马上自动编译部署,修改的结果立刻就可以看到。能够这样做的基础在于,单个工程本身是可打包,可运行的。
但是在这个项目里,根本就不可能,比如我修改了项目A的几个java文件,我总不能再全部编译部署一遍,就只好把修改后的.class手工替换到容器里面去,再重启容器进行验证
2、依赖关系很混乱,比如项目B是依赖于项目A的,那么有这样的情况,即一个小组正在修改项目A,另一个小组正在修改项目B。项目A的修改结果,没有办法实时知会到项目B小组(因为项目B的小组不可能时不时地停下来,去编译一下工程A,然后替换jar包)
所以这样就存在一个代码不同步的问题,可能白天开发的时候都好好的,因为项目B使用了项目A的旧jar包,但是到了晚上统一编译的时候,就会编译不通过,因为项目A的代码,其实在白天也已经变了
3、基础工程不稳定,造成项目非常不稳定。请想象一下这种情况,你的一个项目使用spring、hibernate、commons等多个jar包,但是这些jar包每天都在更新,每天都提供最新的jar包给你。并且每天你不止要编译自己的项目,你要先把这些基础框架编译一遍,再编译自己的项目,这是什么感觉?我感觉这个项目就是这样的一种情况
现状就是如此,我反思总结了以下3个体会:
1、不要盲目拆分工程
一个项目拆分成3个或者4个工程,然后通过某些方式集成起来,或许有一定的合理性,但是一个项目拆分成30多个工程,很难认为这种决策是正确的
2、无论怎么拆分,务必保证每个工程的独立性
即每个工程自己要能够发布成war包,独立地运行起来。否则代码的修改验证就是一场噩梦
3、稳定的工程才打jar包
将代码打成jar包,虽然没有本质区别(一段代码依赖某个类com.xxx.SomeClass,这个类的代码放在工程里,或者放在一个jar包里import进来没有明显区别),但是打成jar包就是进行了一次封装
如果是一个工程中的代码,你可以立刻修改它,看到结果;但是如果是从另一个工程里打出来的jar包,那么如果要修改它的话,那么至少,你要多一个编译打包的过程。这个区别很小,但是有时就会带来很大的麻烦
所以,如果基础工程还不稳定,就不要打成jar包。可以先“裸”在工程里,有问题随时改。这部分代码用了一段时间,经历几个版本,很稳定了,再抽取出来打成jar包也不迟。而不是像这次这个项目一样,好几个所谓的“平台工程”,天天在改代码,天天出新jar,还要打肿脸充胖子
疑惑:
我做过的十来个大大小小的项目,一般都是一个独立的工程,或者是若干个可单独部署的工程组合起来的,像这次这种情况我没有见过。
究竟是这个项目确实错了,还是我个人见识太浅,希望有经验的人可以谈谈看法
分享到:
相关推荐
在IT行业中,自学开发是一种非常常见且有效的方式来提升技能或转行进入这个行业。"自学开发好不好?" 这个标题提出了一个很多初学者都关心的问题。让我们深入探讨一下自学开发的利弊,以及如何有效地进行自学。 ...
但是,这种方式也存在一些缺点,如:与其他使用 Spring 开发项目不好集成。 5. Spring-DM 方式 Spring-DM 方式是 OSGi 服务发布和获取的一种方式。这种方式的优点是 Spring 的方式管理对象(Dependency Injection ...
4. **AsyncTask**:Android提供的一种轻量级的异步任务类,特别适合进行短时间的后台操作,如网络请求,然后更新UI。它有三个泛型参数,分别代表后台执行的任务类型、进度更新类型和结果返回类型。AsyncTask的生命...
易语言是一种中文编程环境,旨在降低编程难度,让普通用户也能进行软件开发。这个项目是为那些想要构建和设计网页的人提供的,通过提供源码,用户可以深入理解网页开发的内部工作原理,并根据自身需求进行定制。 ...
在IT行业中,REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于HTTP协议,以轻量级、无状态、协议简单著称,广泛应用于Web服务接口设计。本项目是作者使用PHP语言开发的一个...
ARM7是一种广泛使用的32位RISC微处理器架构,由英国的ARM公司设计,主要用于嵌入式系统的开发。ARM7架构以其低功耗、高性能的特点,在移动通信、消费电子和工业控制等领域得到了广泛应用。对于初学者而言,学习ARM7...
iFix组态软件是工业控制领域应用非常广泛的一种软件,它集成了组态技术、控制技术、人机界面技术、数据库技术和网络技术,为用户提供了强大的工业自动化解决方案。本文主要探讨了如何基于iFix组态软件开发数据通讯...
注意,此版本不包含源代码,只是一个绿色的可以随时打开的版本,开发工具为:delphi7+sqlserver2000我的PDF(Perfect Developer Frame),想要 简单,快速,健壮,因此我用的还是C/S结构,因为客户可不管你用的是什么最高新的...
**Pascal大小写形式**:这是一种命名方式,其中每个单词的第一个字母都是大写的,其余字母均为小写。这种命名方式通常用于类名、接口名、枚举名、事件名等。 **示例**: ```csharp public class HelloWorld { // 类...
PLC 程序开发中的结构化编程是一种软件工程思想在 PLC 编程中的应用方法,为自控项目中的 PLC 编程提供了一种方法论。通过分层次的编程来构成 PLC 程序,采用这中方法可以实现多人协作,为大型的控制程序进行共同...
:dashing_away: :rocket:用一种简单的方式,声明式描述使用Flutter的动画 前言 据说Flutter动画的时候,我们一般想到的是什么? 如果您照着Flutter文档手册看完,脑子里肯定一堆Tween,AnimationController,...
这个模块的实现基于套接字编程,这是一种在客户端和服务器之间建立连接并进行数据传输的基础技术。理解并掌握在线聊天模块的原理和实现方式对于任何网络开发者来说都是至关重要的。 首先,我们需要了解套接字...
另一种方式,是已知业务产生的数据之间的依赖关系后,直接在数据库中插入相关数据,本项目就是通过这种方式来实现,好处就是生成规则通过配置文件来描述即可(yaml文件),不需要额外添加代码(对于某些字段生成规则...
内容简介:用Netbeans基于Java开发的语义关联词汇检索原型系统,内含源代码,数据库、jar包等. 包含了: ...说明:最好用第一种方式,如果环境配置不好,第二和三种方式可能会出现内存溢出情况。
汇编语言是一种简单易掌握、效率较高的开发语言。 汇编语言可读性非常差、移植性也不好,在处理计算问题上非常复杂,要求的编程技巧较高,所以导致现代单片机系统上更多地使用C语言等高级语言,但汇编语言对于理解...
megetexture是一种高效的技术,用于在3D游戏中处理大规模纹理,特别是在现代游戏引擎中,它允许开发者以更优化的方式存储和管理大量的纹理数据,以提高性能和视觉质量。而idSoftware是一家知名的游戏开发公司,以其...
软件体系结构设计与常用体系结构模型 软件体系结构设计是软件设计过程中的一个重要...软件体系结构模型是描述软件体系结构的一种方式,它可以帮助开发人员更好地理解软件系统的整体特性,并指导软件设计和开发过程。
鸿蒙系统支持两种主要的开发模式:FA(Feature Ability)和PA(Particle Ability)。对于本示例,我们假设已经选择了FA开发模式。 ##### 2. 图片放置位置 - 将需要点击的图片放入项目的资源文件夹中。通常情况下,...
QQ小程序是一种轻量级的应用,它可以在QQ平台上运行,无需用户下载安装即可使用,极大地提升了用户体验。本项目是一个自己动手制作的小型QQ程序,虽然在技术实现上可能并不完美,但作为学习和实践的案例,它包含了...