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

Доброе утро.

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

<?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( );


Собственно, вопрос: как по-красивому в фабрике (или, может, тут нужна не фабрика?) передать параметры от контроллера каждому создаваемому классу ?
  • Вопрос задан
  • 277 просмотров
Решения вопроса 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
ИМХО, на вашу задачу отлично ложится паттерн Стратегия. Ответ, отмеченный как решение, как раз показывает примерную реализацию.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы