如何使列表查找方法遵循单一职责原则?规避非算法类修改
解耦算法与附加职责的实现方案
核心思路
通过依赖注入将日志、进度存储等非核心逻辑从查找算法中完全抽离,让betterContains仅负责元素查找这一项核心职责,所有附加逻辑通过外部传入的回调或观察者实现。
方案一:使用高阶函数(Scala原生特性)
将附加逻辑封装为函数参数,传入查找方法:
核心查找方法(仅负责查找)
def betterContains( list: List[String], element: String, onFound: => Unit, // 找到元素时执行的逻辑 onNotFound: => Unit, // 未找到元素时执行的逻辑 onProgress: Int => Unit // 进度更新时执行的逻辑(参数为剩余元素数) ): Boolean = { if (list.isEmpty) { onNotFound false } else if (list.head == element) { onFound true } else { onProgress(list.tail.size) betterContains(list.tail, element, onFound, onNotFound, onProgress) } }
外部定义附加逻辑
// 日志逻辑单独实现 private def logFound(): Unit = log.info("Yes! found it!") private def logNotFound(): Unit = log.info("The element was not found in the list.") private def logProgress(remaining: Int): Unit = log.info(s"Still searching, $remaining elements pending") // 进度存储逻辑单独实现 private def saveProgress(remaining: Int): Unit = { val writer = new java.io.FileWriter("progress.txt", true) try writer.write(s"Remaining elements: $remaining\n") finally writer.close() }
组合调用
可以灵活组合不同的附加逻辑,比如同时启用日志和进度存储:
betterContains( myList, targetElement, onFound = logFound(), onNotFound = logNotFound(), onProgress = { remaining => logProgress(remaining) saveProgress(remaining) } )
方案二:使用观察者模式(适合多附加逻辑场景)
定义统一的观察者接口,让日志、存储等逻辑实现该接口,查找方法触发事件时通知所有观察者:
定义观察者接口
trait SearchListener { def onFound(): Unit def onNotFound(): Unit def onProgress(remaining: Int): Unit }
实现具体观察者
// 日志观察者 class LoggingListener extends SearchListener { override def onFound(): Unit = log.info("Yes! found it!") override def onNotFound(): Unit = log.info("The element was not found in the list.") override def onProgress(remaining: Int): Unit = log.info(s"Still searching, $remaining elements pending") } // 进度存储观察者 class ProgressStorageListener extends SearchListener { override def onFound(): Unit = {} // 找到元素时无需存储进度 override def onNotFound(): Unit = {} // 未找到时无需存储进度 override def onProgress(remaining: Int): Unit = { val writer = new java.io.FileWriter("progress.txt", true) try writer.write(s"Remaining elements: $remaining\n") finally writer.close() } }
核心查找方法(支持多观察者)
def betterContains( list: List[String], element: String, listeners: List[SearchListener] = Nil ): Boolean = { // 封装通知逻辑 private def notifyFound(): Unit = listeners.foreach(_.onFound()) private def notifyNotFound(): Unit = listeners.foreach(_.onNotFound()) private def notifyProgress(remaining: Int): Unit = listeners.foreach(_.onProgress(remaining)) if (list.isEmpty) { notifyNotFound() false } else if (list.head == element) { notifyFound() true } else { notifyProgress(list.tail.size) betterContains(list.tail, element, listeners) } }
调用方式
传入多个观察者即可同时启用多种附加逻辑:
betterContains( myList, targetElement, List(new LoggingListener(), new ProgressStorageListener()) )
效果说明
- 核心查找方法
betterContains现在仅负责元素查找,只有当需要优化查找算法时才需要修改它。 - 日志、进度存储等附加逻辑完全独立,更换日志库或修改存储方式(比如从文本文件改为数据库),只需修改对应的回调函数或观察者实现,不会影响查找算法。
- 可以灵活组合或禁用附加逻辑,无需修改核心代码。
内容的提问来源于stack exchange,提问作者M.G.
相关产品推荐
相关产品推荐

