关于产品蛋糕模式

问题描述:

Cake Patternarticle建议使用性状命名空间:关于产品蛋糕模式

trait UserRepositoryComponent { 
    val userRepository: UserRepository 
    class UserRepository {...} 
} 

trait UserServiceComponent {this: UserRepositoryComponent => 
    val userService: UserService  
    class UserService {...} 
} 

class Context extends UserServiceComponent with UserRepositoryComponent { 
    val userRepository = new UserRepository 
    val userService = new UserService 
} 

但是我们真的需要这些“命名空间特质”(UserServiceComponentUserRepositoryComponent),如果我们可以做以下?

trait UserRepository {...} 

trait UserService {this: UserRepository => 
    ... 
} 

class Context extends UserRepositoryImpl with UserService

所以,我的问题是什么时候,为什么我们需要在Cake Pattern的“命名空间”的特点。

+1

前段时间,我也在'ru_scala'上回答了您关于DAO的问题,但由于某种原因,它已被主持人屏蔽......这里的要点是:https:/ /gist.github.com/933872。下面的解释对于DAO的问题和当前的问题都是有效的。 – 2011-05-05 13:21:48

+0

@Vasil非常感谢。顺便说一句,为什么你在你的“要点”例子中使用'self'而不是'this'? – Michael 2011-05-05 13:46:33

+1

赋予'this'一个别名(传统上,'self')简化了从inner-classes访问'this'的引用〜> http://*.com/questions/4017357/difference-between-this-and-self-in-自我类型注释 – 2011-05-05 13:53:59

有是2周的缺点在你的方法:

  1. Context得到太多的责任,从UserRepositoryUserService等混合起来的方法;
  2. 在第一个片段中,您可以控制初始化的顺序,或者对某些组件进行延迟 - 例如,您可以制作userRepository a lazy val,这将显着简化测试,如果您只想测试userService(因此,不想引导整个基础设施);

虽然我不会推荐它,但在第一种情况下,您也可以在运行时更改注入实体(使用var s)。

与任何模式一样,当它使您的代码更清晰/更具可读性/更易维护/更可测试时,就需要使用它。

在这种情况下,您可能希望为测试目的创建一个备用上下文,替换“生产”版本中使用的部分或全部组件 - 更容易实现的任务以及更多的自我记录,如果通过文章中概述的模式完成。

正如Vasil指出的那样,这里关注的分离是一件好事(tm),并且几乎是蛋糕模式的全部要点。