php Как реализовать "конструктор" в трейте -- для значений которые нужно инициллизировать один раз (trait)
Primary tabs
Предположим, что у был класс, которому для печати данных разными методами в своем конструкторе приходилось (чтобы не создавать объект каждый раз) одному из своих полей (->outputWriter) присваивать объект конкретного класса (\Codeception\Lib\Console\Output), занимающегося печатью, после чего данное поле использовалось методами:
class IFFAcceptanceTester extends \AcceptanceTester
{
public function __construct(\Codeception\Scenario $scenario) {
parent::__construct($scenario);
$this->outputWriter = new \Codeception\Lib\Console\Output([]);
}
/**
* Хранит класс, с помощью которого можно писать в консоль
* @var \Codeception\Lib\Console\Output
*/
protected $outputWriter = null;
/**
* Специальный маркер для перевод строки один раз за время работы теста
*
* @var boolean
*/
protected $newLineAlreadyExists = false;
/**
* Log additinal info into console
* Вывод дополнительной технической информации о процессе работы теста в консоль.
*
* Поддерживает тэги symfony/console @link https://symfony.com/doc/current/console/coloring.html
*
* @param type $str
*/
public function log($str)
{
$this->checkNewLineNeed();
$message ="⚑ $str";
// echo ("$message \n");
$this->outputWriter->writeln("$message");
}
/**
* Обёртка над print_r() для тестировщика $I
*
* @param type $value
* @param string $comment
*/
public function pre($value, $comment = '')
{
$this->checkNewLineNeed();
if ($comment) {
$comment .= ':';
}
$message =" $comment " . print_r($value, true);
$this->outputWriter->writeln("$message");
}
/**
* Вызывается один раз для перевода строки после вывода имени теста
*/
protected function checkNewLineNeed()
{
if (!$this->newLineAlreadyExists) {
echo "\n";
$this->newLineAlreadyExists = true;
}
}
}
Теперь мы хотим вынести те же методы ->log() и ->pre() в трейт, а с ними и то, на что они опираются -- ведь это позволит использовать логгирование, не только в классах тестера, но и в других независимых от него модулях системы.
Для этого делаем следующее:
- Для инициаллизации $this->outputWriter заводим специальный метод -- назовем его, что не удивительно, outputWriter(), который просто проверяет инициллизировано ли уже значение
- Заменяем все обращения
$this->outputWriter
заменям на вызов
$this->outputWriter()
(уже метода)
В результате получаем:
trait IFFLoggerTrait
{
/**
* Хранит класс, непосредственно занимающийся печать.
* @var object
*/
protected $outputWriter = null;
protected function outputWriter() {
if (!$this->outputWriter) { // если ещё не инициллизировано
$this->outputWriter = new \Codeception\Lib\Console\Output([]);
}
return $this->outputWriter;
}
/**
* Специальный маркер для перевод строки один раз за время работы теста
*
* @var boolean
*/
protected $newLineAlreadyExists = false;
/**
* Log additinal info into console
* Вывод дополнительной технической информации о процессе работы теста в консоль.
*
* Поддерживает тэги symfony/console @link https://symfony.com/doc/current/console/coloring.html
*
* @param type $str
*/
public function log($str)
{
$this->checkNewLineNeed();
$message ="⚑ $str";
// echo ("$message \n");
$this->outputWriter()->writeln("$message");
}
/**
* Обёртка над print_r() для тестировщика $I
*
* @param type $value
* @param string $comment
*/
public function pre($value, $comment = '')
{
$this->checkNewLineNeed();
if ($comment) {
$comment .= ':';
}
$message ="$comment " . print_r($value, true);
$this->outputWriter()->writeln("$message");
}
/**
* Вызывается один раз для перевода строки после вывода имени теста
*/
protected function checkNewLineNeed()
{
if (!$this->newLineAlreadyExists) {
echo "\n";
$this->newLineAlreadyExists = true;
}
}
}
- Log in to post comments
- 5188 reads