Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP OOP访问方法的良好实践?_Php_Oop_Methods - Fatal编程技术网

PHP OOP访问方法的良好实践?

PHP OOP访问方法的良好实践?,php,oop,methods,Php,Oop,Methods,我有一些代码通常是这样的: private $user; public function __construct() { $this->user = User::getInstance(); //singleton } public function methodOne() { return $this->user->foo(); } public function methodTwo() { return $this->user->f

我有一些代码通常是这样的:

private $user;

public function __construct()
{
    $this->user = User::getInstance(); //singleton
}

public function methodOne()
{
    return $this->user->foo();
}

public function methodTwo()
{
    return $this->user->foo2();
}

public function methodThree()
{
    return $this->user->foo3();
}
$user = new UserWrapper(User::getInstance());
我想,如果我将user属性设置为实例,我可以在方法中重用一个较短的名称(在本例中,它并没有那么短)。我还认为这样做可能会节省一些资源(开始怀疑),但当我看别人的代码时,我很少看到有人这样做。他们通常只会打电话:

User::getInstance()->foo();
User::getInstance()->foo2();
User::getInstance()->foo3();
这方面有什么最佳实践吗?如果这不是一门独生子女课程,你可能会这样做?或者你不应该这样做?希望得到一些澄清,谢谢

编辑: 如果有任何误解,我只是想知道我是否应该在第一个示例中创建一个属性来存储实例,而不是:

public function methodOne()
{
    return User::getInstance()->foo();
}

public function methodTwo()
{
    return User::getInstance()->foo2();
}

public function methodThree()
{
    return User::getInstance()->foo3();
}

实际上,现在我想这可能是更少的代码,因为我不需要构造函数…

我个人在PHP中的偏好是只使用静态方法的类来处理单例,所以

User::foo();
User::bar();

我不会创建一个新类,只是为了围绕这样一个单例。但是如果您的新类添加了一些额外的逻辑,那么您的示例就有意义了。请记住,如果您担心过于冗长,您可以始终使用临时变量进行后续函数调用

$user = User::getInstance();
$user->foo();
$user->bar();
但就我个人而言,我不再使用单身。相反,我使用依赖注入。我喜欢sfServiceContainer,但还有其他的。请看本系列文章:

更新

根据其他评论,我将这样做:

class UserWrapper
{
    private $user = null;

    public function __construct($user)
    {
        $this->user = $user;
    }

    public function foo()
    {
         return $this->user->foo();
    }

    ...
}
然后像这样使用它:

private $user;

public function __construct()
{
    $this->user = User::getInstance(); //singleton
}

public function methodOne()
{
    return $this->user->foo();
}

public function methodTwo()
{
    return $this->user->foo2();
}

public function methodThree()
{
    return $this->user->foo3();
}
$user = new UserWrapper(User::getInstance());
为什么??因此,如果我想测试UserWrapper类,我可以传入一个假用户对象。例如:

class UserMock { ... } // A fake object that looks like a User
$userTest = new UserWrapper(new UserMock());

我通常这样做,如果您已经在某种引导或配置文件中包含了该类。我通常会在引导文件中声明$user变量,该变量在每次页面加载时都会被调用,然后在其他php文件中将其作为全局变量引用,这就是我在引导文件中的内容

$user = new User();
那么这就是我在调用php文件中的内容

global $user;
$user->foo();

你的方法确实存在一些问题

  • 不清楚您的类是否依赖于用户类。您可以通过将用户添加为构造函数参数来解决此问题
  • 单身往往是不好的习惯。您的代码演示了原因:它是全局可访问的,因此很难使用它跟踪依赖项(这就指向了上述问题)
  • 静态方法经常被用作全局访问点(响应您看到的人们通常所做的操作User::method())。全局接入点与单例接入点存在同样的问题。它们也更难测试
我也不认为用新对象重复用户对象有什么意义,除非您使用适配器模式。如果你能澄清这一点,我可能会想出一个比通用型更好的替代方案:

class Foo {
    public function __construct(User $user) {
        $this->user = $user;
    }
    public function doXsimplified() {
        $this->user->doXbutMoreComplex($arg1,$arg2, $arg20);
    }
}

可以通过
\uuu callStatic
最简单地实现,我相信在phpYea中使用globals不是“良好的oop实践”之一,也会有一些额外的逻辑。这是一种与另一个应用程序的集成,因此我包装用户类方法,然后决定更改应用程序,而不必重命名所有内容。对于您展示的代码,我是这样做的,但我只是想知道,如果在每个方法中只使用一次实例,那么最好的方法是什么。编辑了我的主要帖子。如果你添加了额外的逻辑,那么你的代码就可以了。我唯一要改变的是,不要在构造函数中获取
User
的实例,而是将其作为参数传递给构造函数(以方便依赖项注入)。抱歉,也许我还没有很好地解释自己,我只是想知道存储变量的实例是否比直接调用实例更好,如上面两个示例所示。我倾向于第二种方式(每次直接呼叫),因为它看起来更清晰。我会使用第一种方式。我已经用一个例子更新了我的答案。编辑了我的帖子,我还创建了包装器,因为它正在与另一个应用程序集成,所以如果我以后更改应用程序,我不必重命名我的所有方法。我也不确定我是否能够使用您显示的方法,因为我还没有用户对象?@Joker包装器的用途很好。您的用户对象在包装器对象出现的那一刻起作用(因为它是用来操纵第三方用户对象的)。因此,如果你在创建另一个用户对象之前或之后创建这个用户对象,不会有什么区别。是的,没有区别,我想我仍然没有很好地描述自己。实际上要简单得多。我想知道是应该将实例存储在构造函数设置的属性中,还是直接获取实例(如上面的两个示例所示)。我想这只是一种偏好?我现在倾向于第二种方式,因为它似乎让事情变得更清楚。@Joker我会遵循“孤立变化”的规则。什么地方最有可能发生变化?如果发生变化,什么将为您节省最多的工作(无论差异有多小)?然而,如果你发现第二个例子更清楚,那就是一个支持这个观点的论点。