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

标签 php mongodb methodology

关于 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/

相关文章:

javascript - 如何在一页上放置两个表格

java - PHP 和 Java 在同一个应用程序上使用两种不同的语言,在 Apache 上使用 PHP,在 Tomcat 上使用 Java

javascript - Facebook 分享 PHP - 检查是否已分享

javascript - 如何从 youtube 视频制作 gif 图像?

python - 将(所有)维基百科数据加载到 mongodb 中?

node.js - 如何在 mongoDB 中插入时转义 $

node.js - MongoDB 架构 - 调用 createIndex() 来设置 expireAt 时出错

oop - 我如何用看似无目标的想法构建面向对象的软件?

methodology - "Continuous Implementation"是什么?

methodology - 什么是瀑布模型的替代方案