如何在公共接口中区分常用与非常用函数?——以PictureList类为例
先明确你的场景背景:
现有类定义如下:
class PictureList { void clear(); void load(json); void clearAndLoad(json); void draw(); }
常规流程要求调用load前必须先执行clear,clearAndLoad封装了这个安全序列,但因特殊场景需要保留单独调用clear和load的能力,导致公共API边界模糊,既想避免误调用,又要兼容特殊需求。以下是具体解决思路:
1. 命名上做显性区分
给专家级(非常规)方法加上辨识度高的前缀/后缀,用命名直接传递「需谨慎使用」的信号。比如修改为:
class PictureList { // 专家级方法:单独调用需自行保证前置条件 void unsafeClear(); void unsafeLoad(json); // 标准常用方法:安全且符合常规流程 void clearAndLoad(json); void draw(); }
开发者看到unsafe前缀的方法,立刻就能意识到这是特殊场景接口,常规情况优先使用clearAndLoad。
2. 文档注释高亮标注
在公共API的注释里用醒目的关键词明确区分常用/非常用属性,同时标注风险:
class PictureList { /** * 【专家级接口】仅用于无需后续加载数据的特殊清理场景 * 风险提示:单独调用后直接执行load会导致数据不一致,常规流程请用clearAndLoad */ void clear(); /** * 【专家级接口】仅用于已确保数据已清理的特殊加载场景 * 风险提示:未调用clear直接使用会引发逻辑错误,常规流程请用clearAndLoad */ void load(json); /** * 【标准接口】常规流程推荐使用:自动完成「清理+加载」的安全序列 */ void clearAndLoad(json); void draw(); }
同时在类的整体注释里说明:优先使用「标准接口」,「专家级接口」仅为特殊场景设计,使用前需确认业务必要性。
3. 拆分接口层级
把常用方法和专家方法拆分为两个接口,从依赖层面明确边界:
// 标准接口:仅暴露常规用法,覆盖90%以上场景 interface StandardPictureList { void clearAndLoad(json); void draw(); } // 专家扩展接口:包含特殊场景方法,需显式声明使用 interface ExpertPictureList extends StandardPictureList { void clear(); void load(json); } // 实现类同时实现两个接口 class PictureList implements StandardPictureList, ExpertPictureList { // 实现所有方法逻辑 void clear() { /* ... */ } void load(json) { /* ... */ } void clearAndLoad(json) { /* ... */ } void draw() { /* ... */ } }
常规开发时依赖StandardPictureList接口,只有特殊场景才会主动使用ExpertPictureList,从根源上减少误调用专家方法的可能。
4. 利用语言特性做访问控制(若支持)
如果使用的语言支持访问级别或约定式限制,比如Java的protected、Python的下划线前缀,可以把专家级方法设置为非公开或半公开:
比如Python中的实现:
class PictureList: def _clear(self): # 专家级方法,仅内部或信任调用方使用 pass def _load(self, json): # 专家级方法 pass def clear_and_load(self, json): # 标准常用方法 self._clear() self._load(json) def draw(self): pass
通过语言特性或社区约定,暗示这些方法不是给普通开发者用的,降低误触概率。
关于单一职责的补充
clearAndLoad看似违反单一职责,但它的核心职责是「提供安全的加载流程」,本质是封装了一个易出错的操作序列,这种封装的价值远大于严格遵守单一职责——比起教条式的规范,减少人为错误、提升代码可靠性才是更实际的目标。
内容的提问来源于stack exchange,提问作者Fractale

