工厂函数
工厂函数,通常是指固定返回特定实例的函数。
一般来说,工厂函数的用法有以下几种。
类的构造函数的参数很多
这种情况比较常出现在调用第三方库时,或者调用自己写的一些比较通用的库的时候(通用很多时候就代表可配置性强),往往在项目中只有少数几个参数需要变动,如果每个地方都写一长串的初始化的话就会显得很冗长。
比如说:
import library
def factory(param1, param2) -> library.Class:
return library.Class(
param1=param1,
param2=param2,
fixed_param1=...,
fixed_param2=...,
fixed_param3=...,
fixed_param4=...,
fixed_param5=...,
# more fixed parameter
)
一个比较实际的例子:
function rubyFactory(text: string, notation?: string): string {
if (notation === undefined) {
return `<span>${text}</span>`
}
return `
<ruby data-notation="${notation}">${text}
<rp>(</rp>
<rt>${notation}</rt>
<rp>)</rp>
</ruby>
`
}
类实例化后有固定的初始化操作
比如说这里对于 SourceNode 的初始化,由于 SourceNode 创建之后要做一些固定的属性设置,将其封装到一个工厂函数能显著提高代码的内聚程度。
class AudioPlayer {
// ...
sourceNodeFactory(buffer: typeof NodeAudioBuffer, loop: boolean) {
const source: any =
this.#audioContext.createBufferSource() // This is the constructor of SourceNode
if (this.#sourceNode) {
source.onended = this.#sourceNode.onended
}
source.buffer = buffer
source.loop = loop
source.connect(this.#gainNode)
this.#sourceNode = source
return source
}
// ...
}
进行抽象
这种情况和第一种情况很像,不过更偏向于增强代码的可读性,而不是方便书写。
比如:
const callbackNameFactory = () => crypto.randomUUID()
一个类组合另一个类,但是不能让两个类过于耦合
class InnerClass:
def __init__(self, param):
pass
class OuterClass:
def __init__(self, inner_instance: InnerClass, param):
self._inner = inner_instance
def outer_factory(param1, param2) -> OuterClass:
inner = InnerClass(param1)
outer = OuterClass(inner, param2)