PHP OOP 访问方法的好习惯?

发布于 2024-10-22 02:08:38 字数 1016 浏览 1 评论 0原文

我有一些代码通常如下所示:

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::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();
}

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

I have some code that often looks like this:

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();
}

I figure if I set user property to the instance I can reuse a shorter name in my methods (well in this case it's not that much shorter). I also thought doing it this way might save a little resources (beginning to doubt it), but when I look at other people's code I rarely see people do this. They would usually just call:

User::getInstance()->foo();
User::getInstance()->foo2();
User::getInstance()->foo3();

Is there any sort of best practice for this? Maybe if it's not a singleton class you might do it this way? Or maybe you should never do it this way? Hope to get some clarification, thanks.

Edit:
Incase there is any misunderstanding I'm just wondering if I should the first example with creating a property to store the instance vs this:

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

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

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

Actually now that I think about it this may be less code as I don't need the constructor...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

粉红×色少女 2024-10-29 02:08:39

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

$user = User::getInstance();
$user->foo();
$user->bar();

但就我个人而言,我不再使用 Singleton。相反,我使用依赖注入。我喜欢 sfServiceContainer,但还有其他的。查看本系列文章:http://fabien.potencier。 org/article/11/what-is-dependency-injection

更新

根据附加评论,我将这样做:

class UserWrapper
{
    private $user = null;

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

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

    ...
}

然后像这样使用它:

$user = new UserWrapper(User::getInstance());

为什么?因此,如果我想测试 UserWrapper 类,我可以传入一个假的 User 对象。例如:

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

I would not create a new class just to wrap around a singleton like that. But if your new class adds some extra logic then your example makes sense. Remember, if you're worried that you're too verbose you can always use a temporary variable for successive function calls.

$user = User::getInstance();
$user->foo();
$user->bar();

But personally, I don't use Singletons anymore. Instead, I use Dependency Injection. I like the sfServiceContainer, but there are others. Have a look at this series of articles: http://fabien.potencier.org/article/11/what-is-dependency-injection

UPDATE

Based on the additional comments, this is how I would do it:

class UserWrapper
{
    private $user = null;

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

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

    ...
}

Then use it like this:

$user = new UserWrapper(User::getInstance());

Why? So I can pass in a fake User object if I want to test the UserWrapper class. E.g:

class UserMock { ... } // A fake object that looks like a User
$userTest = new UserWrapper(new UserMock());
红ご颜醉 2024-10-29 02:08:39

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

$user = new User();

这就是我在调用 php 文件中的内容

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

I usually go like this, if you have already included the class in a bootstrap of some sort or a config file. I would usually declear the $user variable in a bootstrap that will get called on every page load, then just reference it as a global variable on other php files, this is what I would have in the bootstrap file.

$user = new User();

Then this is what I would have in the calling php file

global $user;
$user->foo();
不如归去 2024-10-29 02:08:38

你的做法确实存在一些问题。

  • 目前尚不清楚您的类是否依赖于 User 类。您可以通过添加 User 作为构造函数参数来解决此问题。
  • 单例通常是不好的做法。您的代码演示了原因:它是全局可访问的,因此很难使用它来跟踪依赖项(这指向上述问题)。
  • 静态方法经常被用作全局访问点(响应你所看到的人们通常做的 User::method())。全局访问点会带来与单例相同的问题。它们也更难测试。

我也不认为用新对象重复用户对象有什么意义,除非您使用例如适配器模式。也许如果你能澄清这一点,我就能想出比通用更好的替代方案:

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

There are indeed some problems with your approach.

  • It is not clear that your class depends on the User class. You can solve this with adding User as a constructor parameter.
  • Singletons are often bad practice. Your code demonstrates why: it is globally accessible and hence difficult to track dependencies using it (this points to the above problem).
  • Static methods are too often used as global access points (in response to what you see people usually do User::method()). Global access points give the same problem as singletons. They are also a tad more difficult to test.

I also don't see the point in repeating the User object with your new object, unless you would use eg the adapter pattern. Maybe if you could clarify this I would be able to come up with a better alternative than the generic:

class Foo {
    public function __construct(User $user) {
        $this->user = $user;
    }
    public function doXsimplified() {
        $this->user->doXbutMoreComplex($arg1,$arg2, $arg20);
    }
}
み青杉依旧 2024-10-29 02:08:38

我个人在 PHP 中的偏好是使用仅包含单例静态方法的类,因此您可以

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

My personal preference in PHP is to use classes with just static methods for singletons, so you have

User::foo();
User::bar();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文