Php 在OOP中是否应该避免在方法中传递参数并尽可能多地使用?

Php 在OOP中是否应该避免在方法中传递参数并尽可能多地使用?,php,oop,Php,Oop,下面是一个场景 class page { public $name; public $title; public function showhead() { return "<head><title>".$this->title."</title></head>"; } } $mypage = new page; $mypage->title = "My Page titl

下面是一个场景

class page {
     public $name;
     public $title;

     public function showhead() {
           return "<head><title>".$this->title."</title></head>";
     }
}
$mypage = new page;
$mypage->title = "My Page title";
$mypage->showhead();
类页面{
公共名称;
公有产权;
公共职能展示人(){
返回“$this->title.”;
}
}
$mypage=新页面;
$mypage->title=“我的页面标题”;
$mypage->showhead();
还有另一种情况

class page {
     public $name;
     public function showhead($title) {
           return "<head><title>".$title."</title></head>";
     }
}
$mypage = new page;
$mypage->showhead("My Page title");
类页面{
公共名称;
公共职能展示主管($title){
返回“$title.”;
}
}
$mypage=新页面;
$mypage->showhead(“我的页面标题”);

在这些方法中,哪些更好,哪些应该避免?为什么?

如果没有任何附加信息,我会说第一个“更好”,因为在我看来,
$name
$title
是属于
页面的属性,因此,它应该是类成员。但是,如果你觉得第二个版本更适合你的情况,那就一定要使用它。

我想这取决于你是否需要这个标题。如果确实如此,则创建用于存储和检索的属性。如果您只需要它一次,那么就使用方法参数。

在传递参数(单独传递或在不可变聚合类型中传递,这在PHP中并不存在)和将它们存储在某个位置(无论是类属性、全局属性,还是其他)之间总是存在一些紧张关系。OOP的好处之一是,您可以将状态存储在对象中,并从封装中获益(防止许多意外的数据覆盖),同时避免用变量污染符号表。使用这些可变对象有其自身的问题,特别是当我们进入多线程编程时,但这在PHP中是一个较小的问题

在您的特定情况下,我认为最好将标题存储在对象中。正如silico所说,它似乎属于
页面
,除此之外,您还可以执行以下操作:

$page = new page;
$page->setTitle("whatever");
...
function doStuff($page) {
    ...
    $page->showhead();
}

然后,您不必将
$page
与标题一起传递。

IMO:因为->showhead()与$title的语义关系比对象本身少,所以您应该将$title指定为属性,或者通过对象构造函数更好:

class page {
    function __construct($title="") {
        $this->title = $title
    }

因此,您可以
新建页面(“我的页面”)
或以后分配它
$page->title=…
,这取决于您何时有可用的页面。

关于最佳实践,最好不要直接访问对象成员,而是将其设置为受保护的,并改为通过公共方法进行设置/获取,像这样的

class foo
{
    protected $title;

    public function setTitle($title)
    {
        $this->title = $title;
    }

    public function getTitle()
    {
        return $this->title;
    }
}
这样就不需要使用任何其他代码来处理这些数据,而需要知道这些数据实际上是如何存储的,而是提供了一个接口,从而封装(隔离)了这些数据。

你应该问问自己:标题属于一个页面吗?或者它是页面使用的东西。
以下是我用来找出如何在OOP中设计实体的主要启发式方法:

  • 比较是一种具有-a的关系。页面有标题吗?这个问题的答案是肯定的
  • 继承是一种a是-a的关系。这页是标题吗?这个问题的答案是否定的。请注意,只要可能,您应该更喜欢组合而不是继承。通常你可以使用它们中的任何一个
  • 将参数传递给函数的关系是使用-a。页面是否使用标题?这个问题的答案是肯定的。然而,has-auses-a的关系更强。有时你也可以同时使用这两种方法,但如果可能的话,你应该更喜欢has-a而不是使用-a

更重要的是;现在可以声明属性受保护,从而使对象不可变。输入错误?“尽可能避免和使用”-更改和更改或?