斯卡拉 – 蛋糕模式 – 为什么这么复杂
发布时间:2020-12-16 18:39:51 所属栏目:安全 来源:网络整理
导读:我想了解蛋糕模式. 我正在阅读this博客. 该博客的示例代码是: case class User (name:String,email:String,supervisorId:Int,firstName:String,lastName:String)trait UserRepository { def get(id: Int): User def find(username: String): User}trait Use
我想了解蛋糕模式.
我正在阅读this博客. 该博客的示例代码是: case class User (name:String,email:String,supervisorId:Int,firstName:String,lastName:String) trait UserRepository { def get(id: Int): User def find(username: String): User } trait UserRepositoryComponent { def userRepository: UserRepository trait UserRepository { def get(id: Int): User def find(username: String): User } } trait Users { this: UserRepositoryComponent => def getUser(id: Int): User = { userRepository.get(id) } def findUser(username: String): User = { userRepository.find(username) } } trait UserInfo extends Users { this: UserRepositoryComponent => def userEmail(id: Int): String = { getUser(id).email } def userInfo(username: String): Map[String,String] = { val user = findUser(username) val boss = getUser(user.supervisorId) Map( "fullName" -> s"${user.firstName} ${user.lastName}","email" -> s"${user.email}","boss" -> s"${boss.firstName} ${boss.lastName}" ) } } trait UserRepositoryComponentImpl extends UserRepositoryComponent { def userRepository = new UserRepositoryImpl class UserRepositoryImpl extends UserRepository { def get(id: Int) = { ??? } def find(username: String) = { ??? } } } object UserInfoImpl extends UserInfo with UserRepositoryComponentImpl 我可以通过删除用户来简化该代码: package simple { case class User(name: String,email: String,supervisorId: Int,firstName: String,lastName: String) trait UserRepository { def get(id: Int): User def find(username: String): User } trait UserRepositoryComponent { def userRepository: UserRepository trait UserRepository { def get(id: Int): User def find(username: String): User } } trait UserInfo { this: UserRepositoryComponent => def userEmail(id: Int): String = { userRepository.get(id).email } def userInfo(username: String): Map[String,String] = { val user = userRepository.find(username) val boss = userRepository.get(user.supervisorId) Map( "fullName" -> s"${user.firstName} ${user.lastName}","boss" -> s"${boss.firstName} ${boss.lastName}" ) } } trait UserRepositoryComponentImpl extends UserRepositoryComponent { def userRepository = new UserRepositoryImpl class UserRepositoryImpl extends UserRepository { def get(id: Int) = { ??? } def find(username: String) = { ??? } } } object UserInfoImpl extends UserInfo with UserRepositoryComponentImpl } 它编译得很好. 1)为什么博客中的代码如此复杂? 2)这是使用蛋糕模式的惯用方法吗? 3)为什么在这个例子中需要Users类? 4)那是蛋糕模式看起来的样子(看似不必要的用户类吗? 5)或简化版是否正常? 解决方法
>起初它可能看起来很复杂,但是一旦你熟悉了这种模式,它只是……锅炉和繁琐.对于您的每项服务,您必须创建一个包含该服务的附带组件.因此,在提供的示例中,您有一个由UserRepositoryComponent包装的UserRepository.这只是抽象,因此您需要为组件和服务(即UserRepositoryComponentImpl包装UserRepositoryImpl)提供具体的实现.到目前为止,您只有一个可能在您的模块中使用的服务,想象创建数十个服务的努力;) >是的,这是使用该模式的惯用方法.然而,该模式还有其他变体,例如,薄蛋糕图案或冻糕(由Dick Wall创造的一个术语) >您询问用户,但您的代码简化是删除用户,因此我将描述它们.用户是一个简单的案例类,应该使该示例更容易理解.然而,用户在这里不是必需的(它只是另一个中间抽象级别),在我看来,它们给示例带来了一些不必要的噪音. >我想说你的简化版本确切地显示了蛋糕图案应该是什么样子.你有一个包含在UserRepositoryComponent中的抽象UserRepository,你有这两个特征的具体实现,并且你有一些需要用户存储库的服务(UserInfo)(使用自我类型注释“注入”). >已经回答了.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |