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

Я ищу конкретный совет рефакторинга.

Во-первых, у меня был скрипт только с вычислениями и без вывода. Я хотел закодировать вывод вычислений, чтобы на экране были видны как формулы, так и их фактические значения.

И поэтому я реализовал DEBUG переменные и добавили выходные операторы, чтобы показать, когда DEBUG значение true, Однако моя проблема в том, что мой выходной код оказался тесно связан с вычислениями.

Мой код теперь выглядит так:

$rows = db_query("select..*");
foreach($rows as row)
{
$description = $row['model'];

//dump() prints output on screen
if ($this->DEBUG) dump("<h1>Trying {$description}...</h1>");

if ($this->DEBUG) dump("Checking Speed . . . ");
$this->calcSpeed();

if ($this->DEBUG) dump("Checking Flow . . . ");
$this->checkFlow();
}

А потом внутри calcSpeed например у меня есть вычисления и вывод:

$this->ratio = $this->r / $this->q;
$this->n = ($factor * $this->vel);
$this->t = $this->n * pow($this->r, 0.5) / pow(($this->reject * 2), 0.75);
$this->p = $this->n * pow($this->q, 0.5) / pow(($this->feed * 2), 0.75);

if ($this->DEBUG) dump("<b>Computing Speed</b>");
if ($this->DEBUG) dump("ratio ({$this->ratio})= r({$this->r}) / q({$this->q})");
if ($this->DEBUG) dump("N ({$this->n})= (factor ({$factor}) * vel ({$this->vel})");
if ($this->DEBUG) dump("T ({$this->t}) = N({$this->n}) * QR({$this->q})^0.5 / (reject ({$this->reject}) * 2) ^ 0.75");
if ($this->DEBUG) dump("P ({$this->p}) = N ({$this->n}) * Q({$this->q})^0.5 / (feed ({$this->feed}) * 2)^ 0.75");

То, что я имею выше, тесно связано, и в идеале я хотел бы удалить это соединение и иметь computation быть отдельным от computation output, Я не вижу, как сделать это чисто и без дублирования вычислений. Я хочу видеть вывод всех промежуточных значений, а не только конечный результат.

0

Решение

На самом деле не существует супер-приятного (который я знаю — если есть, пожалуйста, скажите мне!) Способа регистрации, который не инкапсулирован с кодом, который вы регистрируете, однако …

Вы можете скрыть ведение журнала для каждой переменной, используя методологию get / set.

Метод Get / Set с помощью магических методов:

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

Изменить переменную на частную

Переменная должна соответствовать названию методов get / set (например, ratio => getratio / setratio)

Реализуйте методы get / set / __ get и __set

Добавлен метод logger, чтобы сделать оператор if, чтобы методы get / set были максимально чистыми

class MyClass
{
private $ratio;

// Setter method
// Allows for additional work when setting the value
// Here we can output the log as we want then set the value
public function setratio($ratio)
{
logger("ratio ({$this->ratio})= r({$this->r}) / q({$this->q})");
$this->ratio = $ratio;
}

// Getter method
// Allows for additional work when getting the value
// Here we can just retrieve the value of the variable
public function getratio()
{
return $this->ratio;
}

// Magic Method __set
// Here we are able to use Variable Function calls to call the appropriate setter
// This is automatically called when using the syntax $this->ratio = value where ratio is a private property
public function __set($name, $value)
{
$functionName ='set'.$name;
return $this->$functionName($value);
}

// Magic Method __get
// Here we are able to use Variable Function calls to call the appropriate getter
// This is automatically called when using the syntax $this->ratio where ratio is a private property
public function __get($name)
{
$functionName = 'get'.$name;
return $this->$functionName();
}

// Custom function for logging. Only need to call this and it'll check DEBUG for us
public function logger($message)
{
if ($this->DEBUG)
dump($message);
}
}

Таким образом, когда вы звоните calcSpeed у тебя просто есть

$this->ratio = $this->r / $this->q;
$this->n = ($factor * $this->vel);
$this->t = $this->n * pow($this->r, 0.5) / pow(($this->reject * 2), 0.75);
$this->p = $this->n * pow($this->q, 0.5) / pow(($this->feed * 2), 0.75);

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

Это приведёт в порядок цикл следующим образом:

$rows = db_query("select..*");
foreach($rows as row)
{
$description = $row['model'];

//dump() prints output on screen
$this->logger("<h1>Trying {$description}...</h1>");
$this->calcSpeed();
$this->checkFlow();
}

и каждый метод должен быть

function calcSpeed()
{
$this->logger("Checking Speed . . . ")
$this->ratio = $this->r / $this->q;
$this->n = ($factor * $this->vel);
$this->t = $this->n * pow($this->r, 0.5) / pow(($this->reject * 2), 0.75);
$this->p = $this->n * pow($this->q, 0.5) / pow(($this->feed * 2), 0.75);
// Any other code
}

function checkFlow()
{
$this->logger("Checking Flow . . . ")
// Rest of code
}
1

Другие решения

У меня есть общие рекомендации, которые могут потребовать много времени для реализации, но, возможно, они того стоят:

обрабатывать формулы как данные (и обрабатывать данные для формул также как данные).

Для PHP есть библиотека под названием symfony/expression-language, что позволяет оценивать и интерпретировать формулы. С его помощью можно составлять и интерпретировать пользовательские формулы.

Таким образом, я считаю, что можно сделать что-то вроде этого:

  • закодировать формулы в базу данных, которая будет использоваться в качестве одного истинного источника формул
  • (необязательно) использовать библиотеку для компиляции операторов в код PHP
  • интерпретировать формулы из базы данных через библиотеку, для вычислений и для целей регистрации

Образец кода

$expressions = //load from database
$language = new \Symfony\Component\ExpressionLanguage();
$data = array(); //storage of intermediate results.
foreach ($expressions as $expression)
{
/*
* Evaluate the formula
*/
$data[$expression->getVariable()] =
$language->evaluate($expression->getExpression(), $data);

/*
* Add facilities to output the formulas/expressions here:
* example only, where a and b defined in previously-processed formulas
*/
print $expression->getVariable() . ' = ' .       //c =
$expression->getExpression() . ' = ' .     //sqrt(a**2+b**2) =
data[$expression->getVariable()] . '<br>'; //5<br>
}
0

По вопросам рекламы [email protected]