将PHP函数分解为单一任务的函数?

3

我有一个函数,同时执行大约5个任务,这严重违反了面向对象编程的原则。有人能帮我将其拆分吗?特别是在其他函数中调用函数是一种很棘手的问题。

public function status(){
        $client = new Client();
        $notification=Notification::where('active',1)->get();
        $status = Status::where('name', 'health')->first();
        $default_frequency = 1;

        foreach ($notification as $note) {
            $status_health = $note->status('health');

            $check_frequency = isset($note->check_frequency) ? intval($note->check_frequency) : $default_frequency;

            $date = \Carbon\Carbon::parse($status_health['timestamp']);
            $elapsed_time = $date->diffInMinutes();

            if($elapsed_time < $check_frequency){
                continue;
            }

            $response = $client->get($note->website_url, ['http_errors' => false]);   
            $resCode = $response->getStatusCode();

            $note->statuses()->attach($status,['values'=> $resCode === 200 ? 'up' : 'down']);
        }
    }

2
你可以将你想要分成独立方法的5个任务列出来,这样有人可能会帮助你。 - RiggsFolly
是的,因为这个类非常重要,我将会在不同的类中反复调用它的函数。这就是为什么我现在想要对它进行拆分。 - abraham foto
是的,我知道,但是请给我们列出您认为需要拆分成5个新方法的代码中的5个任务列表。我没有看到5个单独的任务,所以显然我很愚蠢,需要您的帮助。 - RiggsFolly
这个类负责发送1个HTTP请求,它会检查时间戳与当前时间以便发送HTTP请求。同时,它会附加一些内容(实际上是HTTP请求的一部分)。 - abraham foto
1个回答

0

我认为你不需要过多地优化代码。如果我理解正确,你正在尝试在一些指定的时间间隔内更新通知的状态。

这可以分为两个任务:

  1. 获取所有通知并循环遍历每一个
  2. 根据某些标准更新每个通知的状态

这是我尝试对你的代码进行简化和优化:

Class YourClass {

    const DEFAULT_FREQUENCY = 1;

    private $client;

    public function __construct(Client $clinet)
    {
        $this->client = $clinet;
    }

    public function status()
    {
        $notifications = Notification::where('active', 1)->get();
        $status = Status::where('name', 'health')->first();

        foreach ($notification as $notification) {
            $this->updateStatus($notification, $status);
        }
    }

    private function updateStatus(Notification $notification, Status $status)
    {
        $status_health = $notification->status('health');

        $frequency = $this->getFrequency($notification);

        $elapsed_time = \Carbon\Carbon::parse($status_health['timestamp'])->diffInMinutes();

        if ($elapsed_time >= $frequency) {
            $response = $this->client->get($notification->website_url, ['http_errors' => false]);   
            $notification->statuses()->attach($status, [
                'values'=> $response->getStatusCode() === 200 ? 'up' : 'down'
            ]);
        }
    }

    private function getFrequency(Notification $notification)
    {
        return isset($notification->check_frequency) 
            ? intval($notification->check_frequency) 
            : self::DEFAULT_FREQUENCY;
    }
}

谢谢回复。如果对我有用,我会阅读并尝试它...感激不尽。 - abraham foto
完美地按预期工作!我真正想要返回这个类的是,如果响应代码不是200,那么它应该...然后我将在另一个类中调用它以发送Slack或电子邮件通知。如果可以的话,能否给我一些提示或帮助? - abraham foto
你可以在你的类构造函数中注入另一个类(类似于我们在“Client”类中所做的)。然后,一旦你检查了 $response 的代码并且不为 200,你就可以调用另一个类的方法进行进一步处理(例如发送通知)。 - Armin Sam
不是注入,我只是想简单地返回HTTP代码,然后在其他类中使用结果,然后决定是否发送通知?如果我们可以尝试编辑您的代码。 - abraham foto
我无法评论关于设计代码的最佳方式,因为我不知道你正在做什么的细节。唯一需要记住的是每个类/函数必须具有单一职责。因此,如果当前类负责更新通知状态,请将代码保留原样,并将其他事情委托给其他类/服务来处理。 - Armin Sam
  1. 你通过构造函数将Slack类作为依赖项传递(做得好),但你没有使用它。相反,你正在使用静态的Slack类(Slack::send(...blablabla))。
  2. 但是GuzzleController类不应该依赖于Slack。而应该依赖于另一个类。我们称之为“Reporter”,它的工作是在需要时向特定频道报告。
- abraham foto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接