内部与外部工厂
|
我正在考虑在PHP中实现工厂模式的两种不同方式之一。我不知道这些变体是否具有正确的名称,因此现在我将其称为内部工厂和外部工厂。
内部工厂:工厂方法在类本身中作为静态公共方法实现。
<?php
class Foo
{
protected
$loadedProps = false;
public static factory ($id)
{
$class = get_called_class ();
$item = new $class ($id);
if ($item -> loadedProps ())
{
return ($item);
}
}
public function loadedProps ()
{
return ($this -> loadedProps);
}
protected function loadPropsFromDB ($id)
{
// Some SQL logic goes here
}
protected function __construct ($id)
{
$this -> loadedProps = $this -> loadPropsFromDB ($id);
}
}
?>
外部工厂:工厂及其初始化的项目被实现为单独的实体
<?php
class Foo
{
protected
$loadedProps = false;
public function loadedProps ()
{
return ($this -> loadedProps);
}
protected function loadPropsFromDB ($id)
{
// Some SQL logic goes here
}
public function __construct ($id)
{
$this -> loadedProps = $this -> loadPropsFromDB ($id);
}
}
abstract class FooFactory
{
public static factory ($id)
{
$item = new Foo ($id);
if ($item -> loadedProps ())
{
return ($item);
}
}
}
?>
现在在我看来,每个人都有其优点。
前者允许您将构造函数与外界隔离。这意味着创建Foo对象的唯一方法是通过工厂。如果无法从数据库中加载商品的状态,则工厂将返回NULL,您可以在代码中轻松检查该商品。
if ($item = Foo::factory ($id))
{
// ...
}
else
{
// The item failed to load. Handle error here
}
工厂还可以创建Foo的任何子类的对象,而无需进行任何修改。
但是,它似乎有一些缺点。首先,班级必须实施工厂,这可能会将责任归于真正属于其他地方的班级。内部工厂版本肯定比外部工厂版本具有更大的类。
至于外部工厂,这很干净,因为工厂本身不在班级中,而且我不必担心班级承担的责任应有尽有。外部工厂也可能更适合于依赖项注入。
但是,它有自己的缺点。首先,工厂要构建的项的构造函数必须是公共的,因为PHP没有包的概念,并且对类成员没有'package'的保护级别。这意味着没有什么可以阻止编码器仅执行新的Foo()并绕过工厂(尽管这可能会使单元测试更加容易)。
另一个问题是FooFactory只能创建Foo对象,而不能创建其任何子类。可以通过在FooFactory中添加另一个参数来指定类名来解决此问题,但是工厂必须对内部指定的对象类实际上是Foo的后代进行内部检查。
因此,基本上,这两种方法的相对优点是什么,您会推荐哪些?
另外,如果它们的名称比内部或外部工厂的名称更合适,我想知道它们。
没有找到相关结果
已邀请:
1 个回复
河饶办斜施