我只是想知道:使用Java 8,并且可以在接口中添加实现(有点像Scala特性),是否可以实现蛋糕模式,就像我们在Scala中可以做的那样?
如果是,有人可以提供代码片段吗?
我一直在阅读通过蛋糕模式在scala中执行依赖注入.我想我明白了,但我一定错过了一些东西,因为我仍然看不到它的重点!为什么通过自我类型而不仅仅是抽象字段来声明依赖性更好?
鉴于编程中 的示例,ScalaTwitterClientComponent使用cake模式声明了这样的依赖关系:
//other trait declarations elided for clarity
...
trait TwitterClientComponent {
self: TwitterClientUIComponent with
TwitterLocalCacheComponent with
TwitterServiceComponent =>
val client: TwitterClient
class TwitterClient(val user: TwitterUserProfile) extends Tweeter {
def tweet(msg: String) = {
val twt = new Tweet(user, msg, new Date)
if (service.sendTweet(twt)) {
localCache.saveTweet(twt)
ui.showTweet(twt)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这比将依赖关系声明为抽象字段更好吗?
trait TwitterClient(val user: TwitterUserProfile) extends Tweeter {
//abstract fields instead of cake pattern self types
val service: TwitterService
val localCache: TwitterLocalCache …Run Code Online (Sandbox Code Playgroud) 在Scala中使用许多较新的语言特性,可以实现可组合的组件系统,并使用所谓的Cake Pattern创建组件,Martin Odersky在可扩展组件抽象论文中以及最近的演讲中描述了这种模式.
Cake Pattern中使用的一些Scala功能具有相应的Haskell功能.例如,Scala implicits对应于Haskell类型类,Scala的抽象类型成员似乎对应于Haskell的关联类型.这让我想知道Cake Pattern是否可以在Haskell中实现以及它看起来像什么.
Cake模式可以在Haskell中实现吗?Scala功能在这样的实现中对应哪些Haskell功能?如果Cake模式无法在Haskell中实现,那么哪些语言功能可能无法实现?
我还在尝试学习Scala的蛋糕模式.在我看来,它为您提供了集中"组件"配置的优势,以及为这些组件提供默认实现的能力(当然这些组件是可覆盖的).
然而,使用自我类型特征来描述依赖关系似乎混合了关注领域.Component(我认为)的目的是抽象出该组件的不同实现.但是Component中描述的依赖列表本身就是一个实现问题.
例如,假设我有一个装满小部件的数据库,一个允许我查找特定种类小部件的注册表,以及一些使用注册表处理小部件的算法:
case class Widget(id: Int, name:String)
trait DatabaseComponent {
def database: (Int => Widget) = new DefaultDatabase()
class DefaultDatabase extends (Int => Widget) {
// silly impl
def apply(x: Int) = new Person(x, "Bob")
}
}
trait RegistryComponent {
this: DatabaseComponent => // registry depends on the database
def registry: (List[Int] => List[Widget]) = new DefaultRegistry()
class DefaultRegistry extends (List[Int] => List[Widget]) {
def apply(xs: List[Int]) = xs.map(database(_))
}
}
trait AlgorithmComponent {
this: RegistryComponent => …Run Code Online (Sandbox Code Playgroud) 我很困惑如何确保我的演员使用蛋糕模式具有适当的依赖关系.我还在忙着解决这个问题,我无法在任何地方找到任何例子.我基本上只是在寻找一个教程/资源.
干杯,克里斯.
我正在尝试使用Cake Pattern在Scala中实现依赖注入,但是遇到依赖冲突.由于我找不到具有此类依赖关系的详细示例,这是我的问题:
假设我们有以下特征(有2个实现):
trait HttpClient {
def get(url: String)
}
class DefaultHttpClient1 extends HttpClient {
def get(url: String) = ???
}
class DefaultHttpClient2 extends HttpClient {
def get(url: String) = ???
}
Run Code Online (Sandbox Code Playgroud)
以下两个蛋糕模式模块(在此示例中都是依赖于我们HttpClient的功能的API ):
trait FooApiModule {
def httpClient: HttpClient // dependency
lazy val fooApi = new FooApi() // providing the module's service
class FooApi {
def foo(url: String): String = {
val res = httpClient.get(url)
// ... something foo specific
???
}
}
}
Run Code Online (Sandbox Code Playgroud)
和
trait BarApiModule …Run Code Online (Sandbox Code Playgroud) 我正在开发一个Play!2.2使用Slick 2.0在Scala中的应用程序我现在正在处理数据访问方面,试图使用Cake Pattern.它似乎很有希望,但我真的觉得我需要编写一大堆类/特征/对象才能实现非常简单的事情.所以我可以对此有所了解.
用一个User概念的一个非常简单的例子,我理解它的方式是我们应该:
case class User(...) //model
class Users extends Table[User]... //Slick Table
object users extends TableQuery[Users] { //Slick Query
//custom queries
}
Run Code Online (Sandbox Code Playgroud)
到目前为止,这是完全合理的.现在我们添加一个"Cake Patternable" UserRepository:
trait UserRepository {
val userRepo: UserRepository
class UserRepositoryImpl {
//Here I can do some stuff with slick
def findByName(name: String) = {
users.withFilter(_.name === name).list
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后我们有一个UserService:
trait UserService {
this: UserRepository =>
val userService: UserService
class UserServiceImpl { //
def findByName(name: String) = {
userRepo.findByName(name) …Run Code Online (Sandbox Code Playgroud) 我尝试在我的项目中使用蛋糕模式并且非常喜欢它,但是有一个困扰我的问题.
当所有组件具有相同的生命周期时,蛋糕模式易于使用.您只需定义多个traits-components,通过traits-implementation扩展它们,然后将这些实现组合在一个对象中,并通过自我类型自动解析所有依赖项.
但是假设您有一个组件(具有自己的依赖项),可以根据用户操作创建该组件.无法在应用程序启动时创建此组件,因为它尚无数据,但在创建时应具有自动依赖性解析.这种组件关系的一个例子是主GUI窗口及其复杂的子项(例如笔记本窗格中的选项卡),它们是根据用户请求创建的.主窗口是在应用程序启动时创建的,当用户执行某些操作时会创建其中的一些子窗格.
这很容易在像Guice这样的DI框架中完成:如果我想要一些类的多个实例,我只需注入一个Provider<MyClass>; 然后我get()在该提供程序上调用方法,并MyClass自动解析所有依赖项.如果MyClass需要一些动态计算的数据,我可以使用辅助注入扩展,但结果代码仍然归结为提供者/工厂.相关概念,范围,也有帮助.
但我想不出用蛋糕模式做这件事的好方法.目前我正在使用这样的东西:
trait ModelContainerComponent { // Globally scoped dependency
def model: Model
}
trait SubpaneViewComponent { // A part of dynamically created cake
...
}
trait SubpaneControllerComponent { // Another part of dynamically created cake
...
}
trait DefaultSubpaneViewComponent { // Implementation
self: SubpaneControllerComponent with ModelContainerComponent =>
...
}
trait DefaultSubpaneControllerComponent { // Implementation
self: SubpaneViewComponent with ModelContainerComponent =>
...
}
trait SubpaneProvider { // A component which …Run Code Online (Sandbox Code Playgroud) 我的开发广泛使用机器人腿绑定问题.我知道如何解决它与PrivateModule在吉斯,但目前尚不清楚如何做到这一点与Scala的蛋糕图案来完成.
有人可以解释一下如何做到这一点,理想情况下,根据Jonas Boner在博客文章末尾的咖啡示例中的具体例子?也许有一个可以配置为左侧和右侧的加热器,注入一个方向和一个def isRightSide?
dependency-injection scala guice cake-pattern robot-legs-problem
我想覆盖trait中的抽象类型<:而不是=(在这里回答Scala Upper Bounds:value不是type参数的成员).
我想用蛋糕模式,但这不起作用,我不明白为什么?
trait A {
def ping = println("ping")
}
trait Cake {
type T
}
trait S { this: Cake =>
type T = A
def t: T
t.ping
}
Run Code Online (Sandbox Code Playgroud)
好的,这个例子运行,但在我的实际用例中,我想覆盖类型<:而不是=.It似乎无法访问t函数,为什么?
trait S { this: Cake =>
type T <: A
def t: T
t.ping
}
Run Code Online (Sandbox Code Playgroud)
返回错误 value ping is not a member of S.this.T