本节摘要:性能优化保得住一个版本,工程规范才保得住许多版本。本节把全书散落的纪律收拢成一套可执行的规范:目录与命名的约定让代码放哪不再需要讨论,公共构件的参数契约让复用不退化成复制,机器检查让规范从"希望大家自觉"变成"越过红线就走不动"。这是维护期工程的核心一课:能自动执行的标准才叫标准,其余叫愿望。
先说清规范失败的常见剧本:团队开会计论、整理文档、全员学习;三个月后新人入职,照着老代码的样子写——而老代码里恰恰还留着没改干净的坏样本。规范靠自觉必然衰减,因为坏样本的说服力永远大于文档。出路是把规范做成墙:机器能查的条目全部接进构建流程,查不过就构建失败。人可以妥协,流水线不会。
青梧书肆的规范墙从最痛的三条砌起,每条都配了对应的机器检查:
| 规范条目 | 为什么 | 机器怎么查 |
|---|---|---|
| 视图脚本存量只减不增 | 防分层溃烂反弹 | 构建时统计页面百分号数量,超基线即失败 |
| 查询语句禁止字符串拼接 | 注入与性能双重病灶 | 扫描数据访问包的拼接特征,命中即失败 |
| 动态输出必须走转义标签 | 脚本注入的出口管控 | 扫描裸的 EL 输出模式,命中即报告 |
| 视图页面一律放私有区 | 防模板与配置被直接访问 | 检查公开区的文件后缀白名单 |
| 会话只存标识与轻量对象 | 防内存缓涨与串单 | 代码评审清单项,机器辅助扫描 |
这套墙的妙处在于它与交接天然亲和:新成员写坏代码的第一天就会被构建拦下,不需要老成员盯着,也不需要他去读那本没人看的规范文档。第 1 章接手时你盼着前任留下这样的墙——现在轮到你砌了。
目录与命名是墙的地基。视图页面住私有区、按业务域分文件夹(用户域、订单域、公共构件域),静态资源独立成区交给前端缓存长存(8.1 节的账);控制器、服务、数据访问、领域对象四包结构沿用第 4 章的契约;公共构件统一住公共域目录。命名跟着位置走:控制器带 Controller 后缀、服务带 Service、数据访问带 Dao,看到类名就知道它在分层里的位置——这份"可预测性"就是规范的全部目的。
复制粘贴是规范墙防不住的另一种退化——它不违反任何语法,却让同一处逻辑活着 N 个漂移的副本。复用的正确姿势在第 3 章埋过伏笔:动态包含配合参数传递,把公共构件做成"带契约的小函数":
<%-- 公共构件:卡片头,声明它需要的参数 --%> <header> <h2>${param.title}</h2> <span>${param.badge}</span> </header> <%-- 调用方:按契约供参 --%> <jsp:include page="/WEB-INF/views/common/card-head.jsp"> <jsp:param name="title" value="热销榜单"/> <jsp:param name="badge" value="本周"/> </jsp:include>
契约的要点是显式:构件需要什么参数,就像方法签名一样白纸黑字——调用方不用读构件内部就能正确使用,构件内部重构只要不破坏契约就不波及调用方。全站构件按此纪律整理一遍后,改页头、改页脚这类需求从"全站搜索替换"变回"改一处文件"。
文案复用是同一思想的延伸:把用户可见的文案从页面里剥出来放进资源文件,页面按键取值。眼下站点只有中文,看似用不上,但这件事的真正收益是改文案不发版——运营要改提示语,改资源文件即可。等真有多语言需求时,从"已剥离"到"已翻译"只差资源文件本身,而不是一场全站大扫除。
背景:翻新进入尾声,你开始写交接文档。写到"工程规范"一章时犯了难:全书的纪律散在十几处,逐条罗列既冗长又没人看。
操作:换一个写法——文档里只写三样东西。一是规范墙的现状:哪几条已接进构建、检查脚本在哪、例外审批流程找谁;二是构件清单:公共构件目录下每份构件的契约(参数名、类型、语义)一览表;三是历史病灶登记表:体检与安全补课发现过的病灶、修复版本、复发时先查哪——7.2 节那套排障链的入口也挂在这一节。
结果:交接文档的规范章节从预想的二十页缩到四页,接手的同事反馈这是全文档最有用的部分。
解读:规范的文档化有一条铁律:能交给机器的绝不写给人看。文档只保留机器管不了的部分——构件契约、例外流程、历史病灶——这些才是接手者真正缺的信息。写文档与砌规范墙是同一件事的两面:墙负责拦截,文档负责解释墙为什么在那。
变式:如果接手的站点一无所有——没有构建流程、没有规范、没有文档——砌墙的顺序也有讲究:先砌最痛的一条(通常是脚本存量或拼接查询),跑稳了再加下一条。一次砌十面墙的结果通常是团队绕墙走,或干脆把墙拆了。
⚠️ 常见坑:规范墙上线后立刻全量收紧,存量代码大面积红灯,团队怨声载道后墙被降级为警告。正确做法是"增量严格、存量设基线":新代码必须过墙,存量按当前水平设为基线只降不升——让墙先活下来,再慢慢收紧。
墙立起来后,真正考验管理能力的是例外:总有场景需要临时跳过检查——紧急修复赶窗口、第三方代码不合规但碰不得、规范本身误报。没有例外出路的管理,结局是团队私开侧门。青梧书肆的例外机制只有三条:例外的批准人唯一(技术负责人)、例外必须带过期时间(最长一个迭代,到期自动恢复拦截)、例外台账公示在交接文档里(谁批的、为什么、何时到期)。这套机制的本质是把"例外"从地下交易变成显式债务——债务可见,才有偿还的可能。顺带一提,例外台账也是新任维护者最该先读的文件之一:里面记录着这个工程全部"明知不合规但暂时不动"的位置,比任何口头交接都诚实。
墙立起来后的日常运营可以固定成一张月历。每月第一件事:看墙的拦截记录——这个月拦了几次、拦的都是什么、是新人犯的还是老兵犯的;某类拦截连续出现,说明规范宣传不到位或规范本身表述不清,该补文档补文档。第二件事:看例外台账的到期项——到期的例外要么还清、要么续期说明理由,台账不允许沉默滚动。第三件事:抽查规范的误报率——规范墙误报三次,团队的敬畏就少三分,误报多的检查项要么调规则、要么降级为警告并公示。第四件事:向团队公示月报——拦截数、例外数、误报数三个数字贴出来,墙的运营透明了,团队才会把它当基础设施而不是管卡。月历的总耗时约一小时,却能让规范墙的生命周期从"三个月热情"延长到"与站点同寿"。
至此,站点的性能、规范都有了交代。下一章抬头看路:把 JSP 与现代模板引擎并排放一放,为这个老站的长期走向做出有依据的判断。