有没有办法告诉类中的所有方法进行函数调用,而无需将函数调用写入每个方法

时间:2016-04-01 17:09:17

标签: scala

我正在编写请求调用数十个应授权的服务。

我注意到我已经在服务类中的所有方法的开头写了很多复制和粘贴代码,因为它们都必须在使用任何服务之前获得授权。

小例子......

class AuthorizationService {
  val authorized = List("James", "007")

  def authorize(user: String) = {
    if (!authorized.contains(user)) throw new RuntimeException(s"User '$user' not authorized")
  }
}

class Service1 {

  val authorizationService = new AuthorizationService

  def doThis(user: String) = {
    authorizationService.authorize(user)
    println(s"User '$user' did this")
  }

  def doThat(user: String) = {
    authorizationService.authorize(user)
    println(s"User '$user' did that")
  }
}

现在假设有30个服务类,每个服务类有三个方法,我继续像我最终编写90个函数调用一样进行授权。

4 个答案:

答案 0 :(得分:1)

这样的事情可能......它仍然需要你的服务改变,但不是那么多:

 object AuthToken {
    implicit def auth(s: String)(implicit service: AuthService) = { 
      service.authorize(s)
      AuthToken(s)
    }
 }
 case class AuthToken private[AuthToken] (s: String) {
    override def toString = s;
 }

 class Service1 {
   implicit val authorizationService = new AuthorizationService
   def doThis(user: AuthToken) = {
     println(s"User '$user' did this")
   }
 }

现在,如果您执行new Service1().doThis("James"),它将隐式调用您的身份验证服务,将名称转换为令牌。

答案 1 :(得分:1)

您可以像这样使用它:

object Tester {

  class AuthorizationService {
    val authorized = List("James", "007")

    def authorize(user: String) = {
      if (!authorized.contains(user)) throw new RuntimeException(s"User '$user' not authorized")
    }
  }


  def authorize(businessLogic: => Unit)(implicit
                                        authorizationService: AuthorizationService,
                                        user: String): Unit = {
    // authorization logic
    authorizationService.authorize(user)
    println(s"User '$user' did this")

    // actual code that needs to be executed
    businessLogic
  }

  class Service1(implicit val authorizationService: AuthorizationService) {
    def doThis(implicit user: String) = authorize {
      println("doThis()")
    }

    def doThat(implicit user: String) = authorize {
      println("doThat()")
    }
  }

  def main(args: Array[String]) {
    implicit val authorizationService = new AuthorizationService
    val s = new Service1()
    s.doThat("James")
    s.doThat("007")
    s.doThat("Neo")
  }
}

答案 2 :(得分:0)

你可以使用原油成分模式:

class ServiceAuthorizationExecutor {
   def call(user: String, delegate: DELGATE_TYPE) = {
      authorizationService.authorize(user)
      delegate()
   }
}

答案 3 :(得分:-1)

这是一个经典的AOP问题。我最后一次看AOP是在12年前,所以我不确定它的状态是什么。