scala pattern_Scala中的DI:Cake Pattern的优缺点

scala pattern

我一直在寻找使用纯Scala的Java风格DI和DI容器的替代方案; 蛋糕模式是一个很有前途的候选人(有关蛋糕模式如何工作的信息,请参阅我以前的博客文章 )。 FP爱好者还声称他们不需要任何DI框架,因为高阶函数就足够了。

最近,Debasish Ghosh也发表了类似主题的博客 。 我认为他的文章是对该主题的很好的介绍。

以下是我在蛋糕图案方面遇到的一些问题。 (高阶功能将在下篇文章中介绍。)如果您对任何一个功能都有解决方案,请告诉我!

使用组件实现参数化系统

首先,无法对具有组件实现的系统进行参数化。 假设我具有三个组件:带有实现的DatabaseComponent,UserRepositoryComponent,UserAuthenticatorComponent,将按以下方式创建系统的顶级环境/入口点:

val env = new MysqlDatabaseComponentImpl
   with UserRepositoryComponent
   with UserAuthenticatorComponent

现在要创建一个具有模拟数据库的测试环境,我将必须做:

val env = new MockDatabaseComponentImpl
   with UserRepositoryComponent
   with UserAuthenticatorComponent

注意多少代码是相同的。 这不是3个组件的问题,但是如果有20个呢? 为了改变一个组件的实现,除了一个组件外,所有其他组件都必须重复。 显然,这会导致很多代码重复。

组件配置

通常需要配置组件。 假设我有一个UserAuthenticatorComponent,它依赖于UserRepositoryComponent。 但是,身份验证器组件具有抽象的val encryptionMethod,用于配置加密算法。 如何配置组件? 有两种方法。 定义环境时,抽象值可以具体化,例如:

val env = new MysqlDatabaseComponentImpl
   with UserRepositoryComponent
   with UserAuthenticatorComponent {
   val encryptionMethod = EncryptionMethods.MD5
}

但是,如果我想重用已配置的组件怎么办? 一个明显的答案是扩展UserAuthenticatorComponent特性。 但是,如果该组件具有任何依赖项(在蛋糕模式中使用自类型表示),则必须重复它们,因为不继承自类型。 因此,可重用的,已配置的组件可能如下所示:

trait UserAuthenticatorComponentWithMD5
         extends UserAuthenticatorComponent  {
   // dependency specification duplication!
   this: UserRepositoryComponent =>
   val encryptionMethod = EncryptionMethods.MD5
}

如果我们不重复自类型,则编译器将抱怨UserAuthenticatorComponent使用不正确。

无法控制初始化顺序

与配置有关的一个问题是,没有一种类型安全的方法来确保以正确的顺序初始化组件。 如上所述,假设UserAuthenticatorComponent具有抽象的encryptionMethod,在创建组件时必须指定该方法。 如果我们还有另一个依赖UserAuthenticatorComponent的组件:

trait PasswordEncoderComponent {
   this: UserAuthenticatorComponent =>
   // encryptionMethod comes from UserAuthenticatorComponent
   val encryptionAlgorithm = Encryption.getAlgorithm(encryptionMethod)
}

并如下初始化我们的系统:

val env = new MysqlDatabaseComponentImpl
   with UserRepositoryComponent
   with UserAuthenticatorComponent
   with PasswordEncoderComponent {
   val encryptionMethod = EncryptionMethods.MD5
}

那么在初始化cryptoAlgorithm时,encryptionMethod将为null! 防止这种情况的唯一方法是在PasswordEncoderComponent之前混入UserAuthenticatorComponentWithMD5。 但是类型检查器不会告诉我们。

优点

不要误会我不喜欢蛋糕模式–我认为它提供了一种很好的方式来构建程序。 例如,它消除了对工厂的需求( 我不是非常喜欢的工厂),或者很好地分离了对组件的依赖和对数据的依赖(*)。 但是,它可能会更好;)。

(*)在这里,每个代码片段实际上都有两种类型的参数:普通方法参数(可用于传递数据)和组件参数(表示为包含组件的自身类型)。 是否应区别对待这两种类型的参数是一个很好的问题:)。

您在Scala中使用DI有哪些经验? 您是否使用Java DI框架,上面使用的方法之一或其他方法?

参考: Scala中的DI: Adam Warski 博客上我们JCG合作伙伴 Adam Warski的 Cake Pattern优缺点

相关文章 :

翻译自: https://www.javacodegeeks.com/2011/10/di-in-scala-cake-pattern-pros-cons.html

scala pattern

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值