什么时候在对象中使用工厂方法而不是factory类是一个好主意?
当前回答
考虑一个场景,当您必须设计Order和Customer类时。为了简单和初始需求,您不需要Order类的factory,并使用许多“new Order()”语句填充应用程序。一切都很顺利。
现在出现了一个新的需求,即Order对象不能在没有客户关联的情况下实例化(新的依赖项)。现在你有以下考虑。
1-你创建了只对新实现有效的构造函数重载。(不可接受)。 2-您更改Order()签名并更改每个调用。(这不是一个很好的练习,而且真的很痛苦)。
相反,如果你已经为Order Class创建了一个工厂,你只需要修改一行代码就可以了。我建议几乎所有聚合关联都使用Factory类。希望这能有所帮助。
其他回答
我把工厂比作图书馆的概念。例如,您可以有一个库用于处理数字,另一个库用于处理形状。您可以将这些库的函数存储在逻辑上命名为Numbers或Shapes的目录中。这些是泛型类型,可以包括整数,浮点数,双元,长或矩形,圆形,三角形,在形状的情况下,五边形。
该系统采用了多态、依赖注入和控制反转等技术。
Factory Patterns的目的是:定义一个用于创建对象的接口,但是让子类来决定实例化哪个类。工厂方法允许类延迟实例化到子类。
假设你正在构建一个操作系统或框架,你正在构建所有的离散组件。
下面是PHP中工厂模式概念的一个简单示例。我可能不会完全理解,但这只是一个简单的例子。我不是专家。
class NumbersFactory {
public static function makeNumber( $type, $number ) {
$numObject = null;
$number = null;
switch( $type ) {
case 'float':
$numObject = new Float( $number );
break;
case 'integer':
$numObject = new Integer( $number );
break;
case 'short':
$numObject = new Short( $number );
break;
case 'double':
$numObject = new Double( $number );
break;
case 'long':
$numObject = new Long( $number );
break;
default:
$numObject = new Integer( $number );
break;
}
return $numObject;
}
}
/* Numbers interface */
abstract class Number {
protected $number;
public function __construct( $number ) {
$this->number = $number;
}
abstract public function add();
abstract public function subtract();
abstract public function multiply();
abstract public function divide();
}
/* Float Implementation */
class Float extends Number {
public function add() {
// implementation goes here
}
public function subtract() {
// implementation goes here
}
public function multiply() {
// implementation goes here
}
public function divide() {
// implementation goes here
}
}
/* Integer Implementation */
class Integer extends Number {
public function add() {
// implementation goes here
}
public function subtract() {
// implementation goes here
}
public function multiply() {
// implementation goes here
}
public function divide() {
// implementation goes here
}
}
/* Short Implementation */
class Short extends Number {
public function add() {
// implementation goes here
}
public function subtract() {
// implementation goes here
}
public function multiply() {
// implementation goes here
}
public function divide() {
// implementation goes here
}
}
/* Double Implementation */
class Double extends Number {
public function add() {
// implementation goes here
}
public function subtract() {
// implementation goes here
}
public function multiply() {
// implementation goes here
}
public function divide() {
// implementation goes here
}
}
/* Long Implementation */
class Long extends Number {
public function add() {
// implementation goes here
}
public function subtract() {
// implementation goes here
}
public function multiply() {
// implementation goes here
}
public function divide() {
// implementation goes here
}
}
$number = NumbersFactory::makeNumber( 'float', 12.5 );
工厂类更重量级,但也有一定的优势。当您需要从多个原始数据源构建对象时,它们允许您在一个地方只封装构建逻辑(可能还包括数据的聚合)。在那里可以进行抽象的测试,而不需要考虑对象接口。
我发现这是一种有用的模式,特别是当我无法替换ORM且ORM不足,并且希望有效地实例化来自DB表连接或存储过程的许多对象时。
当您需要几个具有相同参数类型但具有不同行为的“构造函数”时,它们也很有用。
我简短的解释是,当我们没有足够的信息来创建一个具体的对象时,我们使用工厂模式。我们要么不知道依赖关系,要么不知道对象的类型。我们几乎总是不知道它们因为这是运行时的信息。
示例:我们知道我们必须创建一个车辆对象,但我们不知道它是飞行还是在地面上工作。
假设你有不同的客户,他们有不同的偏好。有人需要大众、奥迪等等。有一样东西是共同的,那就是汽车。
为了让我们的客户满意,我们需要一个工厂。工厂只需要知道客户想要哪一辆车,并将其交付给客户。如果以后我们有另一辆车,我们可以很容易地扩大我们的停车场和工厂。
下面你可以看到一个例子(ABAP):
现在,我们将创建工厂的实例,并监听客户的愿望。
我们只用一个create()方法创建了三种不同的汽车。
结果:
如果你想让逻辑更清晰,程序更可扩展,工厂模式通常非常有用。