0

管理一个复杂的 php oop 应用程序让我有点不知所措。过去,我为我的 'utils' 类使用了静态方法,但我正在编写一个新应用程序,我想尽可能按照最高标准编写代码,所以我希望尽可能避免使用它们。保持可测试性等

我已经研究过依赖注入,但我计划创建一个帮助类的“库”(可以这么说),我可以轻松地进出项目。我的问题是,因为我可能会有五六个这样的,我真的不想设置用户需要将所有这些对象传递到其中的构造。

我的研究把我带到了工厂——我创造了这样一个野兽,但我真的不知道这是否是正确的处理方式。它有点像这样......

class Create {

private static $validation = null;
private static $helper = null;
private static $html = null;
private static $form = null;
public static $user = null;
public static $db = null;

// --------------------------------------------------------------
// Initialize
// --------------------------------------------------------------

public static function load($object, $options, $dependencies = array('html', 'helper', 'db', 'user')) {

    // Create specified object (without constructor)
    // PHP version < 5.4
    $$object = self::createInstanceWithoutConstructor($object);

    // Inject specified options into new object
    foreach($dependencies as $dependency):
        if(is_null(self::$$dependency)): self::$$dependency = new $dependency; endif;
        $$object->$dependency = self::$$dependency;
    endforeach;

    // Now call the constructor
    // PHP version < 5.4
    if(method_exists($$object, '__construct')):
        $$object->__construct($options);
    endif;

    return $$object;

}

// --------------------------------------------------------------
// Create Instance of Object Without Calling it's Constructor
// --------------------------------------------------------------
// Workaround for PHP version < 5.4
// This will be updated to use
// ReflectionClass::newInstanceWithoutConstructor
// when 5.4 is more freely supported
// --------------------------------------------------------------

private static function createInstanceWithoutConstructor($class) {

    $reflector = new ReflectionClass($class);
    $properties = $reflector->getProperties();
    $defaults = $reflector->getDefaultProperties();

    $serealized = "O:" . strlen($class) . ":\"$class\":".count($properties) .':{';
    foreach ($properties as $property){
        $name = $property->getName();
        if($property->isProtected()){
                $name = chr(0) . '*' .chr(0) .$name;
            } elseif($property->isPrivate()){
                $name = chr(0)  . $class.  chr(0).$name;
            }
            $serealized .= serialize($name);
            if(array_key_exists($property->getName(),$defaults) ){
                $serealized .= serialize($defaults[$property->getName()]);
            } else {
                $serealized .= serialize(null);
            }
        }
    $serealized .="}";

    return unserialize($serealized);

}

// --------------------------------------------------------------
// Create User
// --------------------------------------------------------------

public static function User($options = array()) {

    $user = self::load(__FUNCTION__, $options);
    return $user;

}

// --------------------------------------------------------------
// Create Page
// --------------------------------------------------------------

public static function Page($options = array()) {

    $page = self::load(__FUNCTION__, $options);
    return $page;

}

// --------------------------------------------------------------
// Create Form
// --------------------------------------------------------------

public static function Form($name, $method = 'POST', $action = null, $attributes = array()) {

    // Check to see if form was submitted
    // If so, get form object, otherwise create new form object
    if(isset($_POST[$name])):
        $form = unserialize($_SESSION['formObj']);
        $form->errors = array();
        $form->rule = $form->rule;
        $form->labels = $form->labels;
        $form->errors = $form->errors;
    else:
        $form = self::load(__FUNCTION__, array(), array('html', 'validation'));
        $form->name = $name;
    endif;

    // Open the form
    $form->open($method, $action, $attributes);

    return $form;

}

}

因此它具有用于创建各种对象的单独功能,除非显式设置依赖项,否则会传入默认选择。

现在,我真的不确定这是否是一种好方法,从更多的研究中,我收集到为每个负责在该类中创建对象的类拥有一个工厂可能是一个更好的主意。这是更“正确”的处理方式吗?如果是这样,那些工厂方法(不确定这是否是正确的术语?)是否应该只是可以在任何地方调用的静态方法,或者它们可以只是创建新对象然后将它们传入的普通方法?这是否还需要扩展一个包含创建对象的“工厂”类?

希望一切都有意义,任何和所有的帮助都将不胜感激。

你的,

困惑的 N00b。

4

2 回答 2

3

看着你的代码和阅读你的帖子,我觉得你把事情复杂化了。

你不需要关注什么是做某事的“正确”方式。做某事的正确方法是最适合您给定场景的方法。看看你需要做什么,展望未来(但不要太远!!),并尝试找到一个没有过度设计但给你成长空间的解决方案。

我说的未来不会太远,因为开发人员往往过于专注于他们的设计,试图为每一种可能的可能性做计划,而你最终会得到一个无法维护的怪物。

如果静态类中包含的一系列工厂函数正在为您工作,并且您不会很快预见到任何重大问题,那么您为什么需要继续设计?学习做的最难的事情之一就是在为未来设计和完成事情之间走一条线:)

于 2013-08-16T12:42:33.150 回答
0

您列出的内容看起来像是制作服务定位器的错误尝试。这是一种注册表模式。每个班级都应该有特定的目的。因此,使 ServiceLocator 类和工厂类/方法的数量返回实例。然后在应用程序启动时将它们设置为 ServiceLocator。

于 2013-08-16T13:31:19.623 回答