如何无重复扩展固定值集合实现多API兼容的组合过滤器?
优雅解决组合搜索API的过滤器一致性问题
针对你遇到的复制枚举导致代码重复、扩展时易遗漏更新的问题,推荐使用**密封类(Sealed Class)**替代复制枚举的方案,完美适配适配器模式,同时彻底解决一致性问题。
核心思路
用密封类封装两类过滤器:
- 包装原
SearchFilter枚举的通用过滤器 - 新增的动物搜索专属过滤器
密封类的受限特性既能保证所有可能的过滤器类型都被定义,又能自动复用原枚举的所有值,避免重复代码。
完整代码实现
原有代码保持不变
enum class SearchFilter { PERSON, CAR, BUILDING } class GeneralSearch { fun search(filter: SearchFilter) { // 原有业务逻辑 println("执行通用搜索:$filter") } } class AnimalSearch { fun search() { // 原有业务逻辑 println("执行动物搜索") } }
定义密封类替代复制的枚举
sealed class CombinedSearchFilter { // 包装原SearchFilter的枚举实例 data class GeneralFilter(val sourceFilter: SearchFilter) : CombinedSearchFilter() // 新增的动物搜索过滤器 object AnimalsFilter : CombinedSearchFilter() // 伴生对象:提供简洁的静态访问方式,模拟枚举用法 companion object { val PERSON = GeneralFilter(SearchFilter.PERSON) val CAR = GeneralFilter(SearchFilter.CAR) val BUILDING = GeneralFilter(SearchFilter.BUILDING) val ANIMALS = AnimalsFilter } }
实现CombinedSearch适配器
class CombinedSearch( private val generalSearch: GeneralSearch, private val animalSearch: AnimalSearch ) { fun search(filter: CombinedSearchFilter) { when (filter) { // 分发到通用搜索API is CombinedSearchFilter.GeneralFilter -> generalSearch.search(filter.sourceFilter) // 分发到动物搜索API CombinedSearchFilter.AnimalsFilter -> animalSearch.search() } } }
使用示例
fun main() { val combinedSearch = CombinedSearch(GeneralSearch(), AnimalSearch()) // 使用原有过滤器 combinedSearch.search(CombinedSearchFilter.PERSON) // 使用新增过滤器 combinedSearch.search(CombinedSearchFilter.ANIMALS) }
方案优势
- 无代码重复:完全复用原
SearchFilter枚举,无需复制枚举值 - 自动同步扩展:原
SearchFilter新增枚举值时,仅需在密封类的伴生对象中添加对应静态属性即可,Kotlin编译器会在使用未定义属性时报错,避免遗漏更新 - 类型安全:密封类保证所有可能的过滤器类型都被覆盖,
when表达式会强制检查完整性,避免未处理的分支 - 符合适配器模式:统一了两个不同API的调用入口,对外暴露一致的搜索接口
内容的提问来源于stack exchange,提问作者rimes
相关产品推荐
相关产品推荐

