[英]cake pattern Scala
import scala.collection.mutable
class Session
trait SessionProvider:
def session: Session
trait DefaultSessionProvider extends SessionProvider:
val dummySession = new Session
override def session = dummySession
abstract class Identity
trait IdentityCache:
def getOrAuthenticate():Session
trait InMemoryIdentityCache extends SessionProvider:
val cache = mutable.Map.empty[Session, SessionProvider]
override def getOrAuthenticate():InMemoryIdentityCache =
cache.getOrElseUpdate(session, authenticate())
trait Authenticator:
def authenticate():Session
trait UsesSAMLIdentity:
class SAMLIdentity(val saml: String) extends Identity
trait SAMLAuthenticator extends Authenticator with UsesSAMLIdentity:
val dummySAMLIdentity = new SAMLIdentity("XXX")
override def authenticate() = dummySAMLIdentity
trait RoleManager:
def hasRole(role: String): Boolean
trait SAMLRoleManager extends RoleManager with UsesSAMLIdentity:
override def hasRole(role: String): Boolean =
val identity = getOrAuthenticate()
identity.saml == "XXX"
object WebApp extends SAMLRoleManager :
def main(args: Array[String]): Unit =
println(hasRole("YYY")) // Prints "true"
I am new in Scala and I am trying to implement the above code to print true in main.我是 Scala 的新手,我正在尝试实现上述代码以在 main 中打印 true。 My problem is that my IDE says "Not found: authenticate" and "Not found session" in trait InMemoryIdentityCache.
我的问题是我的 IDE 在特征 InMemoryIdentityCache 中说“未找到:身份验证”和“未找到会话”。 I am a little confused about how to implement this cake pattern.
我对如何实现这个蛋糕模式有点困惑。
I will appreciate any help.我将不胜感激。
InMemoryIdentityCache
extends SessionProvider
but doesn't implement session
. InMemoryIdentityCache
扩展了SessionProvider
但没有实现session
。 So whatever extends it would have to provide it.因此,无论扩展它都必须提供它。 From what I see only
DefaultSessionProvider
has it defined, but nothing mixes it in. Actually nobody mixes-in any SessionProvider
as far as I can see).据我所见,只有
DefaultSessionProvider
定义了它,但没有任何东西将它混入其中。据我所知,实际上没有人混入任何SessionProvider
)。
InMemoryIdentityCache
doesn't extend Authenticator
so it cannot access authenticate()
. InMemoryIdentityCache
不扩展Authenticator
所以它不能访问authenticate()
。 If you want to tell compiler that it should extends Authenticator
and a method will be there, you need:如果你想告诉编译器它应该扩展
Authenticator
并且会有一个方法,你需要:
trait InMemoryIdentityCache extends ...:
self: Authenticator =>
The fact that "final" cake might have all the methods doesn't allow you to miss them in the intermediate cake layers. “最终”蛋糕可能具有所有方法的事实不允许您在中间蛋糕层中错过它们。
Also cake pattern is widely recognized as antipattern.蛋糕模式也被广泛认为是反模式。 Rewrite your code to use constructors to inject dependencies and you'll immediately see where there are issues and why.
重写您的代码以使用构造函数注入依赖项,您将立即看到问题所在以及原因。
import scala.collection.mutable
class Session
abstract class Identity
class SAMLIdentity(val saml: String) extends Identity
trait SessionProvider:
def session: Session
class DefaultSessionProvider extends SessionProvider:
val dummySession = new Session
override def session = dummySession
trait Authenticator:
def authenticate(): Identity // you had Session, it didn't work
class SAMLAuthenticator extends Authenticator:
val dummySAMLIdentity = new SAMLIdentity("XXX")
override def authenticate() = dummySAMLIdentity // because your return SAMLIdentity
trait IdentityCache:
// you had Session her as well, even though there is Identity in class name
def getOrAuthenticate(): Identity
class InMemoryIdentityCache(
sessionProvider: SessionProvider,
authenticator: Authenticator
) extends IdentityCache:
val cache = mutable.Map.empty[Session, Identity] // you had [Session, SessionProvider] ?!?
override def getOrAuthenticate(): Identity =
cache.getOrElseUpdate(sessionProvider.session, authenticator.authenticate())
trait RoleManager:
def hasRole(role: String): Boolean
class SAMLRoleManager(identityCache: IdentityCache) extends RoleManager:
override def hasRole(role: String): Boolean =
identityCache.getOrAuthenticate() match {
case identity: SAMLIdentity => identity.saml == "XXX"
case _ => false
}
object WebApp:
def main(args: Array[String]): Unit =
val sessionProvider: SessionProvider = new DefaultSessionProvider
val authenticator: Authenticator = new SAMLAuthenticator
val identityCache: IdentityCache = new InMemoryIdentityCache(sessionProvider, authenticator)
val roleManager: RoleManager = new SAMLRoleManager(identityCache)
println(roleManager.hasRole("YYY")) // Prints "true"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.