You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使列表查找方法遵循单一职责原则?规避非算法类修改

解耦算法与附加职责的实现方案

核心思路

通过依赖注入将日志、进度存储等非核心逻辑从查找算法中完全抽离,让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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 21:05:25