gpt4 book ai didi

scala cake pattern - 我可以有多层蛋糕吗?

转载 作者:行者123 更新时间:2023-12-04 20:17:44 29 4
gpt4 key购买 nike

所以说我的应用程序中有两个依赖项,一个到某个 pub 子系统的连接,一个到一个数据库的连接。我可以做类似的事情

trait DB {
def lookup(query:String):String
}

trait PubSub {
def subscribe(key:String, callback:String => Any)
}

然后我可以像这样写我的逻辑
trait Functionality { this:DB with PubSub => 
def doSomething() {
val key = lookup("get key")
subscribe(key, data => println(data))
}
}

然后我的应用程序可以像
object Awesome extends App {

object repository extends Functionality with DB with PubSub {
def lookup(query:String) = "some key"
def subscribe(key:String, callback:String => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key) ; Thread.Sleep(1000) } }
}
}
repository.doSomething()
}

世界上一切都很好。

但是,如果我想要连接到在同一个应用程序中共享相同数据库实现的两个 pub 子系统怎么办?

我想做类似的事情
object Awesome2 extends App {
object repository extends DB {
def lookup(query: String): String = "some other key"

object connection1 extends Functionality with PubSub with DB {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
}
}

object connection2 extends Functionality with PubSub with DB {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
}
}
}
}

第二层蛋糕中的对象(隐含地?)在父级的数据库实现中啜饮。

但是scala编译器告诉我
error: object creation impossible, since method lookup in trait DB of type (query:String) String is not defined
object connection2 extends Functionality with PubSub with DB {

如果我执行以下操作,那么它会执行我想要的操作
object Awesome3 extends App {
object repository extends DB {
override def lookup(query: String): String = "some other key"

object connection1 extends Functionality with PubSub with DB {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
}

def lookup(query: String): String = repository.lookup(query)
}

object connection2 extends Functionality with PubSub with DB {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
}

def lookup(query: String): String = repository.lookup(query)
}
}
repository.connection1.doSomething()
repository.connection2.doSomething()
}

但这有点乱

我可以添加这个特征
trait DB_Base extends DB {

private val db:DB = this

trait DB_Layer extends DB {
def lookup(query:String):String = db.lookup(query)
}
}

然后下面的作品
object Awesome4 extends App {
object repository extends DB_Base {
override def lookup(query: String): String = "some other key"

object connection1 extends Functionality with PubSub with DB_Layer {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toUpperCase) ; Thread.sleep(1000) } }
}
}

object connection2 extends Functionality with PubSub with DB_Layer {
def subscribe(key: String, callback: (String) => Any) {
scala.concurrent.ops.spawn { while(true) { callback(key.toLowerCase) ; Thread.sleep(1000) } }
}
}
}
repository.connection1.doSomething()
repository.connection2.doSomething()
}

所以现在我有两层。如何获得三个?我觉得我正在失去剧情。

最佳答案

评论不足以解释它,所以这里的答案基本上是说:“不要那样做!”并提出替代方案。

您遇到的关键问题是您希望拥有某些功能的多个副本,但您没有任何方法可以按名称(仅按类型)引用它。解决方案是:给它一个名字。

让我们来看看你的双层蛋糕图案。

trait Foo { def foo(s: String): String }
trait Bar { def bar(s: String, f: String => Any): Any }
trait Bippy { this: Foo with Bar =>
def bip(s: String) = bar(foo(s),println)
}

好的,太好了,我们可以混入 Bippy任何实现 Foo with Bar的东西我们将能够 bip .但是如果 FooBar是在不同的层面实现的吗?如果我们改为
trait Bippy {
def myFoo: Foo
def myBar: Bar
def bip(s: String) = myBar.bar(myFoo.foo(s), println)
}

这最初看起来更尴尬。 (确实如此。)但它现在可以让你混搭,而不是被迫以越来越尴尬的方式结 block 。例如:
object Foozle extends Foo { theFoo =>
def foo(s: String) = s.toUpperCase
trait BippyImpl extends Bippy { this: Bar =>
def myFoo = theFoo
def myBar = this
}
object Woozle1 extends BippyImpl with Bar {
def bar(s: String, f: String => Any) = f(s)
}
object Woozle2 extends BippyImpl with Bar {
def bar(s: String, f: String => Any) = f(s.reverse)
}
}

现在,您可以在任何地方混合和匹配任何功能;唯一的缺点是你必须命名它。 (这里我们创建了一个嵌套的 trait BippyImpl 来拆分 Woozles 的公共(public)部分,但我们可以直接这样做。)

此外,您不会混入原始方法名称;您必须编写代理或引用成员变量。

它错过了蛋糕图案的一些不错的方面,但根据我的经验,它最终比一大堆蛋糕层要清晰得多。现在您可以看到,您可以随意嵌套它,并在任何需要的地方填写您想要的详细信息。

关于scala cake pattern - 我可以有多层蛋糕吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10250404/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com