Задать вопрос

Как сделать фабрику с параметрами?

Доброе утро.

Есть необходимость сделать класс для экспорта табличных данных из приложения: на вход даётся тип и данные, на выход — готовый файл. В коде я вижу это примерно так:

<?php 
	class DataExporter {
		public function Create( $type ) {
			$class = $type . 'Exporter';
			return new $class;
		}
	}

	class AbstractExporter {
		public function setData( $data ) { ... }
		public function getResult( ) { ... }
	}

	class CSVExporter extends AbstractExporter { ... }
	class XLSXExporter extends AbstractExporter { ... }


<?php 
	$data = db::query( 'select * from table' );
	$format = $request->get[ 'format' ];

	$exporter = DataExporter::Create( $format );
	$exporter->setData( $data );
	echo $exporter->getResult( );


Проблема начинается когда хочется передать дополнительные параметры в каждый экспортер. Например, для xlsx - это стиль или ширина столбцов.

<?php 
	class XLSXExporter extends AbstractExporter {
		public function setColumnWidth( $column, $width ) { ... }
		public function setColumnStyle( $column, $style ) { ... }
	}


Прописывать в каждом контроллере что-то вроде кода ниже очевидно неправильно.

<?php 
	$exporter = DataExporter::Create( $format );
	$exporter->setData( $data );

	if( $format == 'XLSX' ) {
		$exporter->setColumnWidth( 0, 100 );
		$exporter->setColumnWidth( 1, 30 );
		$exporter->setColumnWidth( 2, 60 );
	}

	echo $exporter->getResult( );


Собственно, вопрос: как по-красивому в фабрике (или, может, тут нужна не фабрика?) передать параметры от контроллера каждому создаваемому классу ?
  • Вопрос задан
  • 280 просмотров
Подписаться 3 Простой 1 комментарий
Помогут разобраться в теме Все курсы
  • Skillfactory
    Профессия Fullstack веб-разработчик на JavaScript и PHP
    20 месяцев
    Далее
  • Хекслет
    PHP-разработчик
    10 месяцев
    Далее
  • Нетология
    Веб-разработчик с нуля: профессия с выбором специализации
    14 месяцев
    Далее
Решения вопроса 1
dmitriylanets
@dmitriylanets
веб-разработчик
думаю не много не так реализовали, вот если:
$driver = new XLSXExporter();
$exporter = new DataExporter($driver);

echo $exporter->getResult();

class DataExporter{
protected $driver;
function __construct(DriverExporterInterface $driver){
$this->driver = $driver;
}
function getResult(){
return $this->driver->process();
}
}
interface DriverExporterInterface{
public function process();
}


получается:

if( $format == 'XLSX' ) {
    $driver = new XLSXExporter();
    $driver->setColumnWidth( 0, 100 );
    $driver->setColumnWidth( 1, 30 );
    $driver->setColumnWidth( 2, 60 );
  }
else{
$driver = new EmptyExporter();
}

$exporter = new DataExporter($driver);
$exporter->setData( $data );

echo $exporter->getResult();
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
qonand
@qonand
Software Engineer
Для решение этой задачи стоит использовать не фабрику а DI-контейнер
Ответ написан
@KTF
ИМХО, на вашу задачу отлично ложится паттерн Стратегия. Ответ, отмеченный как решение, как раз показывает примерную реализацию.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
FoodSoul Калининград
от 180 000 до 250 000 ₽
IT-Spirit Москва
от 230 000 до 320 000 ₽
от 200 000 до 290 000 ₽