抽象类适合封装报表共用的头尾渲染逻辑,通过模板方法模式固化“头→主体→尾”流程,子类仅需实现具体渲染细节,并支持多格式输出与策略模式解耦样式。

在报表生成系统中,抽象类适合封装所有报表共用的头尾渲染逻辑,比如页眉、页脚、标题栏、导出时间戳、公司 logo 占位等——这些内容与具体数据无关,但每个子报表都要统一处理。
定义抽象报表基类,声明模板方法
创建一个 AbstractReportGenerator 抽象类,把“先渲染头 → 再渲染主体 → 最后渲染尾”这个流程固化为 final generate() 方法,确保子类无法改变执行顺序:
- 头尾逻辑(如写入 HTML 、页眉 div、页脚版权信息)放在 renderHeader() 和 renderFooter() 两个 protected abstract 方法中,由子类实现细节
- 主体数据渲染交给 renderBody(),也设为 abstract,强制子类提供表格/图表等具体内容
- 公共能力(如获取当前时间、读取配置中的公司名称、写入输出流)可直接在抽象类中提供 final 工具方法
子类只需关注业务数据结构,不重复写头尾
比如生成销售报表的 SalesReportGenerator,继承抽象类后只做三件事:
- 重写 renderHeader():插入“销售日报 - {date}”和部门筛选条件栏
- 重写 renderBody():遍历 salesList,拼接
{product} {amount} - 重写 renderFooter():添加“生成于 {now},数据截止至 {endDate}”,并调用 writePageNumber()(抽象类提供的 final 方法)
无需关心 OutputStream 怎么 flush、HTML 标签是否闭合、编码是否 UTF-8 —— 这些都在抽象类的 generate() 里统一封装。
支持多格式输出时复用头尾逻辑
如果系统要同时支持 HTML / PDF / Excel 输出,可在抽象类中定义 OutputFormat 枚举,并让 renderHeader() 等方法接收 format 参数:
- HTML 子类输出 …
- PDF 子类调用 iText 的 HeaderRenderer 或 Document.add() 添加页眉
- Excel 子类用 Apache POI 在 Sheet 第一行写标题行、最后一行写注释
头尾的语义(如“显示标题+时间+页码”)不变,只是实现方式随格式变化 —— 抽象类维持契约,子类专注适配。
配合策略模式解耦样式与结构
若头尾样式需动态切换(如白天/夜间主题、中英文版本),不要把 if-else 塞进抽象类。可将头尾渲染逻辑进一步抽取为接口(如 HeaderRenderer),抽象类持有一个 final HeaderRenderer 字段,构造时注入具体实现:
- ChineseHeaderRenderer 输出“报表生成时间:2024-06-15”
- EnglishHeaderRenderer 输出“Report Generated On: Jun 15, 2024”
- 抽象类的 renderHeader() 只调用 headerRenderer.render(output)
这样既保持抽象类职责单一,又便于测试和替换。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











