Рефакторинг для соответствия принципу СУХОЙ - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь найти способ реорганизовать этот код, чтобы не повторять один и тот же код во многих местах.Я ищу принцип СУХОЙ.

Это пример метода createDaemon().

function createDaemon($server, $command, $user)
    {
        try {
            DB::beginTransaction();

            $model = $server->daemons()->create([
                'command' => $command,
                'user' => $user,
            ]);

            $shell = $this->getCommand('add-daemon', [
                'daemonId' => $daemon->id,
                'command' => $command,
                'user' => $user,
            ]);

            $this->pushToQueue($model, $shell);

            DB::commit();
        } catch (\Exception $e) {
            DB::rollback();
            throw $e;
        }

        return $model;
    }

Это еще один пример createRule() в другом классе, как вы можете видеть, код почти такой же.Как преобразовать это в принцип СУХОГО - вы бы создали новый метод или класс для выполнения той же логики?

   public function createRule($server, $name, $port, $ipAddress = null)
    {
        try {
            DB::beginTransaction();

            $model = $server->rule()->create([
                'name' => $name,
                'port' => $port,
            ]);

            $shell = $this->getCommand('rule', [
                'port' => $port,
                'ipAddress' => $ipAddress
            ]);

            $this->pushToQueue($model, $shell);

            DB::commit();
        } catch (\Exception $e) {
            DB::rollback();
            throw $e;
        }

        return $model;
    }

Ответы [ 2 ]

0 голосов
/ 30 сентября 2018

Расширения

Вы можете сделать так, чтобы они расширяли один и тот же базовый класс:

class foo{
     public function myMethod(){}
}

class bar extends foo{ }

class biz extends foo{ }

Теперь у обоих подклассов есть метод myMethod

Черта

Вы можете использовать черту для общей функциональности

trait foo{
   public function myMethod(){}
}

class bar{
  use foo;
}

class biz{ 
  use foo;
}

Что касается фактической функциональности, я бы разбил ее на 3 метода: я собирался написатьчто-то на нем, но я вижу @Marcin Nabiałek, есть хороший ответ на эту часть.Я просто хотел рассказать о том, как структурировать классы, чтобы повторно использовать общий метод.

Cheers.

0 голосов
/ 30 сентября 2018

Думаю, я бы создал один общий метод, подобный этому:

public function createGeneralRule(Closure $closure)
{
    try {
        DB::beginTransaction();

        [$model, $shell] = $closure();

        $this->pushToQueue($model, $shell);

        DB::commit();
    } catch (\Exception $e) {
        DB::rollback();
        throw $e;
    }

    return $model;
}

, и теперь вы можете использовать его следующим образом:

function createDaemon($server, $command, $user)
{
    return $this->createGeneralRule(function() use ($server, $command, $user) {
        $model = $server->daemons()->create([
            'command' => $command,
            'user' => $user,
        ]);

        $shell = $this->getCommand('add-daemon', [
            'daemonId' => $daemon->id,
            'command' => $command,
            'user' => $user,
        ]);

        return [$model, $shell];
     }
}

и

public function createRule($server, $name, $port, $ipAddress = null)
{
    return $this->createGeneralRule(function() use ($server, $name, $port, $ipAddress) {
        $model = $server->rule()->create([
            'name' => $name,
            'port' => $port,
        ]);

        $shell = $this->getCommand('rule', [
            'port' => $port,
            'ipAddress' => $ipAddress
        ]);

        return [$model, $shell];
     }
 }

Конечно, вы также можете использовать классы, но это действительно зависит от того, сколько раз вы собираетесь использовать этот код и какая гибкость вам действительно нужна.

При использовании классов это может быть что-то вроде этого:

abstract class Rule
{
    public function process()
    {
        try {
            DB::beginTransaction();

            $model = $this->model();
            $shell = $this->shell();

            $this->pushToQueue($model, $shell);

            DB::commit();
        } catch (\Exception $e) {
            DB::rollback();
            throw $e;
        }

        return $model;
    }

    protected function getCommand($name, $data)
    {
        // here you put implementation you had before of getCommand
    }

    abstract protected function model();

    abstract protected function shell();
}

class Deamon extends Rule
{
    protected $server;
    protected $command;
    protected $user;

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

    protected function model()
    {
        return $this->server->daemons()->create([
            'command' => $this->command,
            'user' => $this->user,
        ]);
    }

    protected function shell()
    {
        return $this->getCommand('add-daemon', [
            'daemonId' => $daemon->id, // this is unknown, should be passed in constructor?
            'command' => $this->command,
            'user' => $this->user,
        ]);
    }
}

и в вашем контроллере вы будете использовать его так:

(новый Деймон ($ server, $ command, $ user)) -> process ();

Простов случае - имейте в виду, что у вас есть переменная $deamon, которая не определена (она также не определена в вашем контроллере)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...