扁平结构vs包装结构选型:两种ISearchAttemptBody接口对比
接口选型:ISearchAttemptBody 两种设计方案的选择
问题背景
我们需要为某函数定义接口契约,现有两种ISearchAttemptBody设计方案:方案一将用户详情封装在data字段中,方案二采用扁平结构直接平铺用户字段。请给出选型偏好并说明理由。
相关代码定义如下:
export interface IContactSource { id: string; type: string; } export interface IContactSearchAttempt { firstName: string; lastName: string; email: string; title: string; accountName: string; linkedinUrl?: string; source: IContactSource; } export enum ISearchAttemptOperation { "CONTACT_PROFILE" = "CONTACT_PROFILE", "ACCOUNT_PROFILE" = "ACCOUNT_PROFILE", } // 方案一:带data字段的封装结构 export interface ISearchAttemptBody { operation: ISearchAttemptOperation; data: IContactSearchAttempt; attempt?: number; } // 方案二:扁平结构 export interface ISearchAttemptBody { operation: ISearchAttemptOperation; firstName: string; lastName: string; email: string; title: string; accountName: string; linkedinUrl?: string; source: IContactSource; attempt?: number; }
选型偏好:优先选择方案一
理由:
- 扩展性更强:从
ISearchAttemptOperation能看到有CONTACT_PROFILE和ACCOUNT_PROFILE两种操作,目前方案一的data用了IContactSearchAttempt,后续如果ACCOUNT_PROFILE需要完全不同的参数结构,直接把data改成联合类型(比如data: IContactSearchAttempt | IAccountSearchAttempt)即可,不用修改接口里的其他字段,不会让接口随着操作类型增加变得臃肿不堪。 - 语义边界清晰:把核心业务数据(用户详情)和元数据(操作类型、重试次数)做了明确分离,看接口定义时一眼就能区分哪些是控制类参数,哪些是业务类参数,维护和理解成本更低。
- 复用现有类型:直接复用已定义好的
IContactSearchAttempt,不用重复定义一堆字段,减少代码冗余的同时,也避免了重复定义可能带来的不一致问题(比如后续修改IContactSearchAttempt的字段类型,扁平结构很容易漏改)。 - 兼容性更好:后续新增其他搜索操作类型时,接口的主体结构不需要变动,只需要新增对应的数据结构类型即可,调用方的适配成本更低,不会破坏现有调用逻辑。
内容的提问来源于stack exchange,提问作者Jha Nitesh
相关产品推荐
相关产品推荐

