gpt4 book ai didi

php - MongoDB - PHP - 工厂方法实现

转载 作者:可可西里 更新时间:2023-11-01 09:36:13 26 4
gpt4 key购买 nike

关于 PHP 工厂方法实现的文章很多。我想在 PHP 中为我的 MongoDB 实现实现这样的方法。

我写了如下代码。请查看该代码。

<?php
class Document {

public $value = array();

function __construct($doc = array()) {
$this->value = $doc;
}

/** User defined functions here **/
}

class Collection extends Document {
//initialize database
function __construct() {
global $mongo;
$this->db = Collection::$DB_NAME;
}

//select collection in database
public function changeCollection($name) {
$this->collection = $this->db->selectCollection($name);
}

//user defined method
public function findOne($query = array(), $projection = array()) {
$doc = $this->collection->findOne($query, $projection);
return isset($doc) ? new Document($doc) : false;
}

public function find($query = array(), $projection = array()) {
$result = array();
$cur = $this->collection->find($query, $projection);

foreach($cur as $doc) {
array_push($result, new Document($doc));
}

return $result;
}

/* Other user defined methods will go here */
}

/* Factory class for collection */

class CollectionFactory {
private static $engine;

private function __construct($name) {}
private function __destruct() {}
private function __clone() {}

public static function invokeMethod($collection, $name, $params) {
static $initialized = false;

if (!$initialized) {
self::$engine = new Collection($collection);
$initialized = true;
}

self::$engine->changeCollection($collection);

return call_user_func_array(array(self::$engine, $name), $params);
}
}

/* books collection */
class Books extends CollectionFactory {
public static function __callStatic($name, $params) {
return parent::invokeMethod('books', $name, $params);
}
}

/* authors collection */
class Authors extends CollectionFactory {
public static function __callStatic($name, $params) {
return parent::invokeMethod('authors', $name, $params);
}
}

/* How to use */

$books = Books::findOne(array('name' => 'Google'));
$authors = Authors::findOne(array('name' => 'John'));

Authors::update(array('name' => 'John'), array('name' => 'John White'));
Authors::remove(array('name' => 'John'));
?>

我的问题是:-

  1. 这是工厂方法的正确 PHP 实现吗?
  2. 此实现是否有任何问题?
  3. 对于这种情况,是否有更好的方法?

谢谢大家的回答。

最佳答案

  1. 嗯,不,因为在您的代码中,您使集合类上的所有方法都可用于静态调用。这不是(抽象)工厂模式的目的。
  2. (魔术)方法,如 __callStaticcall_user_func_array 非常棘手,因为开发人员可以使用它来调用每个方法。
  3. 你真正想做什么?实现工厂模式或使用静态单行方法来实现 MongoDB?!

如果书籍和作者集合的实现有不同的方法(比如 getName() 等),我推荐这样的方法:

class BookCollection extends Collection {
protected $collection = 'book';

public function getName() {
return 'Book!';
}
}

class AuthorCollection extends Collection {
protected $collection = 'author';

public function getName() {
return 'Author!';
}
}

class Collection {
private $adapter = null;

public function __construct() {
$this->getAdapter()->selectCollection($this->collection);
}
public function findOne($query = array(), $projection = array()) {
$doc = $this->getAdapter()->findOne($query, $projection);
return isset($doc) ? new Document($doc) : false;
}

public function getAdapter() {
// some get/set dep.injection for mongo
if(isset($this->adapter)) {
return $this->adapter;
}
return new Mongo();
}
}

class CollectionFactory {
public static function build($collection)
{
switch($collection) {
case 'book':
return new BookCollection();
break;
case 'author':
return new AuthorCollection();
break;
}
// or use reflection magic
}
}

$bookCollection = CollectionFactory::build('book');
$bookCollection->findOne(array('name' => 'Google'));
print $bookCollection->getName(); // Book!

编辑:静态单行方法示例

class BookCollection extends Collection {
protected static $name = 'book';
}

class AuthorCollection extends Collection {
protected static $name = 'author';
}

class Collection {
private static $adapter;

public static function setAdapter($adapter) {
self::$adapter = $adapter;
}
public static function getCollectionName() {
$self = new static();
return $self::$name;
}

public function findOne($query = array(), $projection = array()) {
self::$adapter->selectCollection(self::getCollectionName());
$doc = self::$adapter->findOne($query, $projection);
return $doc;
}
}

Collection::setAdapter(new Mongo()); //initiate mongo adapter (once)
BookCollection::findOne(array('name' => 'Google'));
AuthorCollection::findOne(array('name' => 'John'));

关于php - MongoDB - PHP - 工厂方法实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28824547/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com