我正在尝试实现我认为是工厂类的东西。我有一个API框架。在我的前端控制器处理完请求后,它会尝试将输出返回给客户端。我的前控制器中的呼叫如下:
<?php
...
$response_obj = new Response($response_str, 'json');
echo $response_obj->render();
?>
我的Response
类基本上将第二个参数作为要实例化的类的类型,并将$response_str
的内容传递给这个新类。这是:
<?php
class Response {
public function __construct($data, $format) {
switch ($format) {
case 'json':
$obj = new ResponseJson($data);
break;
}
return $obj;
}
}
然后我的ResponseJson
类看起来如下:
<?php
class ResponseJson {
protected $data;
public function __construct($data) {
$this->data = $data;
return $this;
}
public function render() {
header('Content-Type: application/json');
return json_encode($this->data);
}
}
然而,在我的前端控制器中,$response_obj
将其类型返回为Response
,而不是预期的ResponseJson
,并且对render()
方法的调用(存在于ResponseJson
中,而不是Response
中)会引发致命错误:
致命错误:调用第61行/Users/Martin/Sites/api framework/index.php中的未定义方法Response::render()
我哪里错了?
工厂通常被实现为一个静态函数,可以在不实例化工厂类的对象的情况下调用。然后,它创建一个类的对象实例(在的大多数情况下,与您的情况一样,是另一个类)并返回该实例。
你的响应类应该是这样的:
<?php
class Response {
static public function create($data, $format) {
switch ($format) {
case 'json':
$obj = new ResponseJson($data);
break;
case default:
return NULL; // or throw exception!
break;
}
return $obj;
}
}
你的前端控制器是这样的:
<?php
...
$response_obj = Response::create($response_str, 'json');
echo $response_obj->render();
?>
我想你误解了工厂模式:
构造函数方法是在类实例化为对象时自动调用的,我相信你知道。
对象的实例化总是返回对象本身,对象的实例化返回除自身之外的任何东西,尤其是不同类型的对象,这违反了很多逻辑。由于这个规则,构造函数方法不能返回,它总是只在实例化时被调用,从而返回对象本身。
我不完全清楚你的背景,但在这种情况下,你想要一个工厂似乎很奇怪,我希望ResponseJson扩展响应,而不是由它创建的。
希望这能有所帮助!
如果你真的想实现一个工厂模式,你可以做一些事情,比如:
//Pseudo-code
class ResponseFactory
{
createJSONResponse($data)
{
return new JSONResponse($data);
}
createXMLResponse($data)
...
createDefaultResponse($data)
{
return createJSONResponse($data);
}
}
不过,对于响应类型(可能只有2或3种),我认为我会使用Kaii的静态工厂方法。
作为对您评论的回应,我更喜欢标准工厂的原因,每种方法看起来都像上面的,而不是:
createResponse($type, $data)
{
if ($type == 'json')
return new JSONResponse($data);
else if (...)
...
}
特别是因为在许多情况下,你的来电者看起来像:
$response = createResponse('json', $data);
我更喜欢这个:
$response = createJSONResponse($data)
尽管我应该注意到php将字符串作为函数调用的能力可以创建一个非常优雅(尽管有些不安全)的抽象工厂。