接口定义能力契约,抽象类封装接入骨架:接口聚焦行为声明(如paymentclient)、方法名用动宾短语、参数用不可变对象;抽象类提供模板流程(如execute→preprocess→dorequest→postprocess)、强制依赖注入、protected final共享状态;组合使用时客户端extends抽象类+implements多个接口,命名与文档需体现职责分离。

接口与抽象类不是并列替代关系,而是分工协作:接口划清“能做什么”的边界,抽象类固化“怎么接入”的骨架。写得清晰,关键在职责不重叠、语义不模糊、扩展不破环。
接口只声明能力契约,不掺杂实现细节
接口应聚焦行为定义,保持正交、稳定、易测。每个接口对应一个明确能力维度,比如 PaymentClient 只暴露 pay() 和 refund(),不出现重试、签名、序列化等接入逻辑。
- 方法名用动宾短语,如
sendNotification()、validateOrder(),避免模糊词如doAction() - 参数类型尽量用不可变对象或接口(如
ChargeRequest而非Map<string object></string>) - Java 8+ 中可谨慎使用
default方法,仅限无状态、通用校验逻辑(如空值检查),复杂流程仍交给抽象类
抽象类封装可复用的接入流程和强制约束
抽象类是 SDK 的“启动器”和“粘合层”,它把初始化、配置加载、模板调用、工具调用等共性逻辑收拢,同时用抽象方法锁定子类必须补全的关键环节。
- 提供带参构造器,强制传入必要依赖(如
HttpClient、Config),避免子类自行 new 或静态单例 - 定义
protected final字段保存共享状态(如baseUrl、signer),子类不可覆盖但可读取 - 用模板方法模式组织流程,例如
execute(Req req)内部调用preprocess()→doRequest()(抽象)→postprocess(),其中只有doRequest()强制子类实现
组合使用时明确分层与继承路径
一个具体 SDK 客户端通常 extends 抽象类 + implements 多个接口,体现“是什么”和“能做什么”的分离。
- 抽象基类(如
BasePaymentClient)负责 HTTP 封装、重试、日志、指标等通用骨架 - 接口(如
PaymentClient、Refundable、AsyncCapable)按能力切片,支持用户按需组合 - 最终实现类(如
AlipayClient)继承基类并实现所需接口,既获得接入便利,又对外暴露清晰能力标签
命名与文档要同步体现契约意图
命名是架构契约的第一层表达。接口名以 able、Client、Service 结尾(如 Retryable、MetricsClient),抽象类名带 Base、Abstract 或领域关键词(如 AbstractWechatClient)。
- 所有抽象方法必须有 Javadoc,说明“为什么必须实现”而非“怎么实现”,例如:
/** 返回用于生成签名的密钥对,不可为空 */ - 接口中的常量应有业务含义(如
TIMEOUT_SECONDS = 15),避免裸数字或魔法字符串 - 在模块 README 或 JavaDoc 概述中明确写出:“本 SDK 遵循『接口定义能力,抽象类封装接入』原则”
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











