有关测试和界面污染的问题

我几周前开始使用Scala 。 总的来说,我非常喜欢这种语言给开发人员的所有功能,但有时候很难从Java习惯转换。

这个问题是关于特质的。 目前几乎每次我看到我将提取到Java不同类的逻辑的一部分,并向依赖类添加构造函数参数时,我正在切换到创建特征并将其混合到我的类中。 (如果你只有一把锤子,一切看起来都像钉子一样)

但我发现我的方法存在两个问题。

测试混合特质的课程:

Java如果我class Foo使用BarBaz类,我可能会将它们注入到我的Foo类中并使用它们。 如果我使用特质来做到这一点,我会让class Foo extends Bar with Baz

现在在我的测试中,我不得不写一些类似的东西

trait BarMock extends Bar{
    override def bar = "barMock"
}

trait BazMock extends Baz{
    override def baz = "bazMock"
}

val foo = new Foo with BarMock with BazMock

如果我想交换一些特质行为的实现。 也许这只是我习惯写作而已

Bar bar = mock(Bar.class);
when(bar.bar()).thenReturn("barMock");
Baz baz = mock(Baz.class);
when(baz.baz()).thenReturn("bazMock");
Foo foo = new Foo(bar, baz);

像我在Scala项目中展示的那样模拟特质是否正常? 或者我应该抑制自己在测试中混入嘲弄的特质。

特质方法的可见性

这也与我目前对特质的痴迷有关。 在Java如果我将Bar, Baz实例注入到Foo实例中,我不会自动将Bar, Baz所有公共方法添加到我的Foo接口。 如果我想这样做,我必须手动添加每种授权方法。 如果我使用特质,当我混入某些特质时,我会用我的特质中的方法自动“污染” Foo界面。 有什么办法可以实现类似C++私有继承吗?

我想到的唯一解决方案是将trait方法声明为protected ,并将特征标记为package private。 这样,方法将在Foo中可见,但在包外,有人不能写val bar:Bar = new Foo 。 同样,如果我理解正确,只有当包私有特质源代码将在我的项目中时,才会验证包私有约束,因为JVM无法表示私有包的概念,编译器只是在字节码中公开它。


总之:蛋糕。 蛋糕模式。 关于它的文章已经写得很多,最为边缘化,但一旦这个概念进入你的脑海,它很容易实现。 它是实现SOLID以及可测试性和静态类型依赖注入以及混合匹配组件化代码的绝佳工具。

这是有代价的,但我曾经觉得价格需要一个特定的理由来使用Cake来处理给定的代码,我现在可以看到它。 你应该证明不要逐个使用它。

关于Cake的开创性论文是Scalable Component Abstractions(这是一个付费墙,但它在'Net'的其他地方免费提供)。 尽管如此,与大多数这样的事情一样,这不是最好的开始。 只需在Web上搜索“Scala Cake Pattern”就会产生很多点击。 阅读一些内容,直到找到引导你的一个...

链接地址: http://www.djcxy.com/p/82699.html

上一篇: questions about testing and interface pollution

下一篇: Method inheritance in immutable classes