Php 提取到返回为空的方法
所以我有一个更新客户状态的方法。这个方法也在进行一些验证,我认为验证应该分开,并且Php 提取到返回为空的方法,php,refactoring,Php,Refactoring,所以我有一个更新客户状态的方法。这个方法也在进行一些验证,我认为验证应该分开,并且updateCustomerStatus方法应该只更新(出于单一责任的目的) 如果firstCondition或secondCondition保持不变,那么我什么也不做。否则,状态将更新,这将针对客户id列表运行。另外,我将这些条件分开,因为每个条件的消息都是特定的 因此,我有如下几点: private function updateCustomerStatus($customerId) { $custom
updateCustomerStatus
方法应该只更新(出于单一责任的目的)
如果firstCondition
或secondCondition
保持不变,那么我什么也不做。否则,状态将更新,这将针对客户id列表运行。另外,我将这些条件分开,因为每个条件的消息都是特定的
因此,我有如下几点:
private function updateCustomerStatus($customerId) {
$customer = findCustomerById($customerId);
[...]
if (firstCondition($customer)) {
echo "first condition text"; // not actually a echo, so I can't simply return the text
return ;
}
if (secondCondition($customer)) {
echo "second condition text"; // same as above
return ;
}
updateCustomer($customerId);
}
如何将条件提取到方法中
我尝试过重构它,但由于我有空的返回(return;
),我似乎无法理解它,而且我也无法删除它们,因为当特定条件成立时,应该显示特定消息,而它实际上不是回显,这是用于显示消息的另一个无效方法
提前谢谢 我该怎么做:
interface CustomerValidationInterface
{
public function isValid(Customer $customer): bool;
}
class CustomerFooValidator implements CustomerValidationInterface
{
public function isValid(Customer $customer)
{
return $customer->foo === 'FOO';
}
}
class CustomerBarValidator implements CustomerValidationInterface
{
public function isValid(Customer $customer)
{
return $customer->bar === 'BAR';
}
}
class CustomerValidator
{
private $validators;
/**
* @param CustomerValidationInterface[] $validators
*/
public function __construct(array $validators)
{
$this->validators = $validators;
}
public function check(Customer $customer)
{
foreach ($this->validators as $validator) {
if ($validator->isValid($customer) === false) {
return 'error';
}
}
return 'success'
}
}
您可以对代码进行未来验证,如果将来需要验证更多内容,只需创建一个实现接口的新类并传递给主验证器类
更新客户状态IMHO应该按照它说的做,更新客户状态,而不是检查验证。在此之前,您应该执行验证1步。我将如何执行:
interface CustomerValidationInterface
{
public function isValid(Customer $customer): bool;
}
class CustomerFooValidator implements CustomerValidationInterface
{
public function isValid(Customer $customer)
{
return $customer->foo === 'FOO';
}
}
class CustomerBarValidator implements CustomerValidationInterface
{
public function isValid(Customer $customer)
{
return $customer->bar === 'BAR';
}
}
class CustomerValidator
{
private $validators;
/**
* @param CustomerValidationInterface[] $validators
*/
public function __construct(array $validators)
{
$this->validators = $validators;
}
public function check(Customer $customer)
{
foreach ($this->validators as $validator) {
if ($validator->isValid($customer) === false) {
return 'error';
}
}
return 'success'
}
}
您可以对代码进行未来验证,如果将来需要验证更多内容,只需创建一个实现接口的新类并传递给主验证器类
更新客户状态IMHO应该按照它说的做,更新客户状态,而不是检查验证。在此之前,您应该执行验证1步。我建议重构代码,使updateCustomerStatus()方法只包含业务逻辑,即在允许更新之前检查客户的不变量 当前,您将在此方法内调用UI逻辑(即使回音发生在单独的方法中)。我想将UI的实际呈现移出updateCustomerStatus() 我甚至会更进一步,将数据库访问部分(findCustomerById())移出业务逻辑方法 通过这种方式,您还可以单独测试业务逻辑,而无需担心UI和数据库 因此,在重构代码时,我会朝着这个方向前进: 因此,让我们从自上而下的一些虚构的公共方法开始,该方法协调步骤并调用您的私有方法:
public function doUpdateCustomerStatusStuff(string $customerId): void
{
$customer = $this->findCustomerById($customerId);
$operationResult = $this->updateCustomerStatus($customer);
if ($operationResult->failed()) {
$this->showMessage($operationResult->getMessage());
}
}
如您所见,它首先从数据库中获取客户,这样您的业务逻辑现在就可以在客户对象上运行,而不必依赖数据库
在下一步中,我们将研究重构的updateCustomerStatus()方法:
我现在传入Customer对象而不是id,这样逻辑代码就可以完成它的工作了
现在转到原始问题:
我没有调用UI方法(使用echo语句),而是返回一些Result对象,指示操作是成功还是失败,并提供可选消息。为了方便起见,我向OperationResult类添加了一些静态方法
让我们看一看这个类,它并不复杂,但它完成了它的工作:
class OperationResult
{
/**
* @var bool
*/
private $success;
/**
* @var string
*/
private $message;
private function __construct(bool $success)
{
$this->success = $success;
}
private function setMessage(string $message)
{
$this->message = $message;
}
public static function fail(string $message)
{
$result = new OperationResult(false);
$result->setMessage($message);
}
public static function succeed()
{
return new OperationResult(true);
}
public function failed()
{
return !$this->success;
}
public function succeeded()
{
return $this->success;
}
}
现在回到虚构的DoUpdateCustomerStatusTuff()方法:
现在,您可以控制在执行带有所有检查和更新规则的业务逻辑后,何时以及如何输出消息(如果有)
您甚至可以更进一步,将所有业务逻辑方法(例如updateCustomerStatus()移动到一个只包含业务逻辑的单独类中)
注意:我只是假设firstCondition()和secondCondition()将检查错误条件。但是如果不是这样的话,您当然也可以执行消息的输出,这取决于doUpdateCustomerStatusTuff()方法中是否有消息。我建议重构您的代码,使updateCustomerStatus()方法只包含业务逻辑,即,在允许更新之前检查客户的不变量 当前,您将在此方法内调用UI逻辑(即使回音发生在单独的方法中)。我想将UI的实际呈现移出updateCustomerStatus() 我甚至会更进一步,将数据库访问部分(findCustomerById())移出业务逻辑方法 通过这种方式,您还可以单独测试业务逻辑,而无需担心UI和数据库 因此,在重构代码时,我会朝着这个方向前进: 因此,让我们从自上而下的一些虚构的公共方法开始,该方法协调步骤并调用您的私有方法:
public function doUpdateCustomerStatusStuff(string $customerId): void
{
$customer = $this->findCustomerById($customerId);
$operationResult = $this->updateCustomerStatus($customer);
if ($operationResult->failed()) {
$this->showMessage($operationResult->getMessage());
}
}
如您所见,它首先从数据库中获取客户,这样您的业务逻辑现在就可以在客户对象上运行,而不必依赖数据库
在下一步中,我们将研究重构的updateCustomerStatus()方法:
我现在传入Customer对象而不是id,这样逻辑代码就可以完成它的工作了
现在转到原始问题:
我没有调用UI方法(使用echo语句),而是返回一些Result对象,指示操作是成功还是失败,并提供可选消息。为了方便起见,我向OperationResult类添加了一些静态方法
让我们看一看这个类,它并不复杂,但它完成了它的工作:
class OperationResult
{
/**
* @var bool
*/
private $success;
/**
* @var string
*/
private $message;
private function __construct(bool $success)
{
$this->success = $success;
}
private function setMessage(string $message)
{
$this->message = $message;
}
public static function fail(string $message)
{
$result = new OperationResult(false);
$result->setMessage($message);
}
public static function succeed()
{
return new OperationResult(true);
}
public function failed()
{
return !$this->success;
}
public function succeeded()
{
return $this->success;
}
}
现在回到虚构的DoUpdateCustomerStatusTuff()方法:
现在,您可以通过所有检查和更新rul来控制在业务逻辑之后何时以及如何输出消息(如果有)