让我们假设我们有一个特质T
。什么是实现最好的办法如下:在斯卡拉强制实施工厂的简明方法
- 大家谁写的
T
的实现应该被强迫提供一种可能性,即允许T
无参数初始化,即,我们可能不得不强制执行一个可配置的工厂。 - 所有逻辑/数据仅取决于实际的初始化参数(某个实施
A
的T
)应集中处理/存储,但应在工厂和A
中提供。
最简单的/简洁的方式我认为实现这一目标(大约)将添加一个特质的一家工厂,并链接T
此工厂:
trait T {
val factory: TFactory
}
trait TFactory {
def build(): T
val description: String // example for logic/data that only depend on the parameters
}
// example implementation:
class A(val factory: AFactory, paramA: Int, paramB: Int, paramC: Int) extends T
class AFactory(paramA: Int, paramB: Int, paramC: Int) extends TFactory {
def build = new A(this, paramA, paramB, paramC)
val description = f"$paramA $paramB $paramC"
}
显然,这并没有真正“强制执行“工厂的实施(只要有替代实施可用),显然可以生成A
的实例,其链接到”错误的“TFactory
。我也不喜欢这种方法是重复初始化参数。我经常创建另一个类AParams
,它再次包装所有参数(例如,以便于添加新参数)。因此,我最终得到了三个类,对于这个简单的问题,imho是很多样板。
我的问题是,是否有(可能完全)不同的方法,实现相同的主要目标,但更简洁?
肯定是一个有趣的想法,谢谢!我看到的一个实际问题是,直觉上我会失去一个工厂轻量级的概念,而'T'的实际实现可能相当重量级。经常在我的用例中构造一个真正的'A'会涉及大量的初始化,导致产生一个具有相当大内存占用空间的'A'实例。我可能最终会得到一个'A'的实例,我从来没有真正将它用作'T'的实际意义上,而只是作为具有不必要开销的工厂。但也许这是简化的代价。 – bluenote10
看起来你需要在你的工厂中使用T的构造函数参数,所以我没有看到你如何拥有这样的工厂而没有T的实例。除非像你说的那样,你将参数包装在类可以提供给工厂和T的子类的构造函数。 –
从设计角度讲purefly如果不是构建T的唯一方法,我不确定你需要执行这样一个工厂。想必你有一些需要一个工厂,它可以是仅仅一个功能的方法:'MakeTsAndDoUsefulThings(工厂:()=> T)'。 然后在未来,如果我是你的代码在客户端做'SonOfT',发现我需要使用的功能,我会为implment'SonOfT'工厂,可能在我的同伴对象,使这个呼叫:'MakeTsAndDoUsefulThings( SonOfT.defaultFactory)' 如果我从来不需要用这个方法,我将永远不需要做工厂,这似乎确定。 –