这是工厂模式的工作原理吗?

Jas*_*vis 8 php design-patterns factory-pattern

Singleton和Registry模式非常简单,我很容易立即理解,但Factory模式已经让我的大脑无法100%解释.我想我现在可能会理解它,我在下面写了一个示例代码,请查看并告诉我这是否正确使用了Factory模式.样本是用PHP ...

<?php
 /**
 *   Factory.class.php
 */
class Factory {
    public static $_database;
    public static $_cache;
    public static $_session;

    // Build our User object with all it's dependencies  
    public static function makeUserObject()
    {
        $user = new User();
        $user->setDatabaseObject(self::$_database);
        $user->setCacheObject(self::$_cache);
        $user->setSessionObject(self::$_session);
        return $user;
    }

    // other objects will be here someday......
}

/**
 *  User.class.php
 */
class User
{
    public function __construct() { }

    // inject Database Object
    public function setDatabaseObject($databaseConnectionObject)
    {
        $this->_databaseObject = $databaseConnectionObject;
    }

    // inject Cache Object
    public function setCacheObject($cacheObject)
    {
        $this->_cacheObject = $cacheObject;
    }

    // inject Session Object
    public function setSessionObject($sessionObject)
    {
        $this->_sessionObject = $sessionObject;
    }

    // other methods here for User object...........
}

/**
 *  index.php  Main page that puts it all together
 *  assume that classes are autoloaded into this page already
 */
// Set our Database + Cache + Session objects into the Factory Object
Factory::$_database = new Databse();
Factory::$_cache = new Cache();
Factory::$_session = new Session();

// Create our User object
// The factory class will build the User object and inject all
// it's dependencies for us =)
$user = Factory::makeUserObject();

?>
Run Code Online (Sandbox Code Playgroud)

所以基本上创建了Database,Cache和Session对象(这里没有显示),然后将它们添加到Factory对象中,我可以在工厂类中为每个需要这3个依赖项中的任何一个的对象构建一个方法,我可以设置他们也得到了哪些.这也使得各个类仍然可以在某种程度上可移植,因为我可以直接注入依赖项,如果我想没有工厂对象.这听起来不错吗?如果这是对的,这听起来真的很有用


更新#1

这是基于这里我在这里阅读的博客文章http://www.potstuck.com/2009/01/08/php-dependency-injection/他们称之为"工厂",我一直在使用注册表和很多人一直告诉我要看一个"工厂",我读到的所有内容都没有点击我的脑袋,直到我读到这个艺术品,但看起来它不是"工厂"?


更新#2
来自维基百科http://en.wikipedia.org/wiki/Factory_object 在面向对象的计算机编程中,工厂对象是用于创建其他对象的对象.它是构造函数的抽象,可用于实现各种分配方案,例如单例模式.工厂对象通常具有用于其能够创建的每种对象的方法.这些方法可选地接受定义对象创建方式的参数,然后返回创建的对象.工厂对象用于获取特定类型的对象比简单地创建新对象更复杂的情况.工厂对象可能决定动态创建对象的类(如果适用),从对象池返回它,对对象执行复杂配置或其他事情.

所以这可能是一个"工厂对象",毕竟...

Gor*_*don 6

从这里的问题下面总结并扩展了我的评论

像其他人说的那样,它不是工厂,只是因为不存在具有此名称的模式.它既可以是AbstractFactory,也可以是FactoryMethod,虽然实际上人们经常提到或只是说Factory,这对我来说很好.

会话,缓存和数据库通常是您在应用程序流程中尽早初始化的东西,因此这基本上是自举工作.我得到的印象是你要找的不是对象的创建,而是整个应用程序的处理.这与FactoryWhatever的内容有些不同.

就像我在评论中所说的那样,仅仅因为它不是一个FactoryWhatever,并不代表你的代码是坏的.如果它解决了你的问题,那很酷.但我仍然认为,您正在尝试做的事情,例如在运行时创建管理资源最好与DI 服务 容器一起使用.

如果你不希望使用DI容器,现在对于这一点,你可以看看Zend_Application以及它们如何引导资源.它是一种替代方案,可以在以后添加DI容器.

实际上,您之前的问题中的很多主题已经在Zend Framework中得到了解决,例如Config类.我不是说使用ZF,但是你可以看看它们是如何做的.当然,您也可以查看其他 框架.

一些带有PHP示例的模式站点:


Anu*_*rag 5

这是工厂模式好的,但您可能需要一个更好的命名约定,而不仅仅是调用它Factory.它还包含依赖注入的痕迹.

虽然你在技术上可以称之为工厂模式,但它可能不是模式的好用法.Factory是一种创建模式,它封装您的代码,直接引用类名称和对象创建,如精确的构造函数参数等.为了获得最佳结果,请在设计类和工厂时牢记这一点.

例如,StackOverflow根据用户的信誉得分为用户提供不同的权限.假设它可以有以下类型的用户:

NewbieUser      [1-100]
BeginnerUser    [101-1000]
AverageJoeUser  [1001-5000]
VeteranUser     [5001-20000]
PowerUser       [20001-50000]
GodModeUser     [50001-100000]
Run Code Online (Sandbox Code Playgroud)

并且可以通过查找他们的代表来创建用户.并通过直接引用该类来实例化相应的用户对象.如果您想知道,Jon Skeet不会出现在任何类别中.这是一个直接实例化的糟糕实现:

if(reputation >= 1001 and reputation <= 5000) {
    AverageJoeUser user = new AverageJoeUser();
}
Run Code Online (Sandbox Code Playgroud)

如果稍后我们要更改类名或用户实例化的方式,则必须找到并更改创建对象的每个此类实例.如果你问我,相当多的工作.相反,如果我们在这里使用了Factory模式,那么更改将在Factory类中的单个方法中进行.

class UserFactory {
    public static User createUser(Integer reputation) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 朱利安 - 如果你不得不问,那你就不知道了. (3认同)