工厂模式可以减轻添加依赖项的痛苦,因为工厂可能包含状态,实际上可以封装多个依赖项(例如,不是提供三个依赖项,所有这些依赖项都需要调用某个对象的构造函数,您现在只提供一个工厂对象,其中工厂包含需要提供给构造函数的这三个对象)。
举个例子,比较一下:
void DoIt(const DependencyA& a, const DependencyB& b) {
// NOTE: "x" is a contrived additional variable that we add here to
// justify why we didn't just pass DependencyC directly.
int x = ComputeX();
std::unique_ptr<DependencyC> dependency_c(new DependencyC(a, b, x));
dependency_c->DoStuff();
}
和:
void DoIt(const DependencyCFactory& factory) {
int x = ComputeX();
std::unique_ptr<DependencyC> dependency_c(factory->Create(x));
dependency_c->DoStuff();
}
请注意,第二个版本需要对“DoIt”方法的依赖较少。这并不意味着整个程序不需要这些依赖项(实际上,程序在工厂的实现中仍然使用了DependencyA和DependencyB)。但是,通过以这种方式构建它,可以将依赖项隔离到工厂代码,这使其他代码更简单,更容易更改DependencyC
(现在只有工厂本身需要更新,而不是每个地方都需要更新)实例化DependencyC
),甚至可以有一定的安全/保障好处(例如,如果DependencyA
和DependencyB
是敏感的,例如数据库密码或 API 密钥,将它们的使用限制在工厂可以减少错误处理的机会,例如,与在需要使用数据库或 API 的任何地方传递这些信息的情况相比)。
在书中给出的例子中,有一个工厂Order
会有所帮助的原因是它会减少直接使用构造函数的地方的数量;只需修改创建工厂的一个地方以将其存储Customer
为工厂的附加字段;工厂的其他用途都不需要修改。相比之下,在不使用工厂的情况下,直接使用构造函数的情况比比皆是,而且它们中的每一个都必须更新才能以某种方式获得对Customer
对象的访问权。