gpt4 book ai didi

php - 使用特征将代码从一个大类拆分为多个文件怎么样?

转载 作者:可可西里 更新时间:2023-11-01 13:30:29 26 4
gpt4 key购买 nike

来自 Ruby,我很高兴发现 PHP 特性。它们类似于 ruby​​ 的模块系统,我喜欢它。

现在我读了很多帖子说 PHP traits 是邪恶的,因为它们破坏了 OO 设计,你不能像测试类那样容易地测试它们,等等。

我想知道使用 traits 将一个非常大的类分成更易读的部分是否是个好主意。

这个类已经很大了,如果不进行重构,很可能会长达数千行。

尽管方法可以按关注点分组,但它们经常需要相互调用,这让我想知道将类拆分为不同的类是否是最优的。

为了说明,这是我想出的一个简化示例。

大类:

/**
* Class to refactorize
*/

class Tourist
{
public function gotoRestaurant()
{

}

public function gotoInternetCafe()
{

}

public function checkEmails()
{

}

public function meetGirlfriend()
{
if (Girlfriend::location() === 'restaurant')
{
$this->gotoRestaurant();
}
else
{
$this->checkEmails();
}
}

public function checkEmailsAndMeetGirlfriend()
{
$this->checkEmails();
$this->meetGirlfriend();
}
}

如果用类重构,我会这样做:

/**
* Solution 1: using classes
*/

class ChoreDoer
{
public function __construct(Tourist $t)
{
$this->tourist = $t;
}

public function checkEmails()
{
$mover = new Mover($this->tourist);
$mover->gotoInternetCafe();
}

public function meetGirlfriend()
{
if (Girlfriend::location() === 'restaurant')
{
$mover = new Mover($this->tourist);
$mover->gotoRestaurant();
}
else
{
$this->checkEmails();
}
}
}

class Mover
{
public function __construct(Tourist $t)
{
$this->tourist = $t;
}

public function gotoRestaurant()
{

}

public function gotoInternetCafe()
{

}
}

class Tourist
{
public function checkEmailsAndMeetGirlfriend()
{
$cd = new ChoreDoer($this)
$cd->checkEmails();
$cd->meetGirlfriend();

}
}

我有一种感觉,不断地调用 new Mover()new ChoreDoer(),并且将出现的新类将变得难以阅读和写。

那么在这里使用 traits 来分组功能呢?

/**
* Solution 2: using traits
*/

trait TouristMovements
{
public function gotoRestaurant()
{

}

public function gotoInternetCafe()
{

}
}

trait TouristChores
{
public function meetGirlfriend()
{
if (Girlfriend::location() === 'restaurant')
{
$this->gotoRestaurant();
}
else
{
$this->checkEmails();
}
}

public function checkEmails()
{
$this->gotoInternetCafe();
}
}

class Tourist
{
use TouristMovements, TouristChores;
public function checkEmailsAndMeetGirlfriend()
{
$this->checkEmails();
$this->meetGirlfriend();
}
}

这里每个trait都可以专注于它的目的,代码易于阅读,方法可以自由互操作。但是由于我从未打算在 Tourist 以外的任何类中使用 TouristsMovements 特性,所以我觉得我对它们的使用并不是真正设计特性的目的。

您会采用解决方案 1 吗?解决方案 2?还有别的吗?

最佳答案

作为替代方案,您可以使用“解决方案 1”执行类似的操作:

class ChoreDoer
{
private $mover;

public function __construct(Tourist $t)
{
$this->tourist = $t;
}

public function checkEmails()
{
$this->getMover()->gotoInternetCafe();
}

public function meetGirlfriend()
{
if (Girlfriend::location() === 'restaurant')
{
$this->getMover()->gotoRestaurant();
}else
{
$this->checkEmails();

}
}
/**
* lazy-load mover object
*/
private function getMover()
{
if($this->mover == null)
{
$this->mover = new Mover($this->tourist);
}
return $this->mover;
}
}

如果您不喜欢使用 setter/getter ,您可以将您的属性命名为类似

private $_mover;

然后使用魔法 __get 为您调用 getter:

function __get($property)
{
$method = 'get'.ucfirst($property);
if(method_exists($method))
{
return $this->$method();
}
}

虽然这不会执行得很好,但它可以很容易地调用

$this->mover->gotoInternetCafe();

而且干净整洁。

关于php - 使用特征将代码从一个大类拆分为多个文件怎么样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24469164/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com