Factory pro vice podobnych komponent
- marty666
- Člen | 26
Ahoj mam v aplikaci dve podobne komponenty. Vlastne oboje delaji to same, akorat, kazda pouziva jiny model.
Priklad:
namespace App\Components;
class ControlTabsFactory {
private static $types = array(
'car' => array(
'class' => 'CarTabs',
'model' => 'App\Model\Cars'
),
'person' => array(
'class' => 'PersonTabs',
'model' => 'App\Model\Persons'
),
);
public function create($type) {
if (in_array($type, array_keys(self::$types))) {
$class = self::$types[$type]['class'];
$model = self::$types[$type]['model'];
return new $class(new $model(/* pripojeni k databazi */));
}
throw new \Exception('Sorry bro! You are not my type. :D');
}
}
Pripadam si, ze toho pisu zbytecne moc a, ze by to za me nette mohlo nejak
vycarovat samo (autowiring).
Nejde to nejak z jednodusit, nebo jak tam pripadne dostat to pripojeni k db?
Dekuji za rady.
Editoval marty666 (9. 9. 2014 12:51)
- marty666
- Člen | 26
Tak jsem to zkousel podle tohoto navodu: https://doc.nette.org/…tion/factory
namespace App\Components;
class ControlTabsFactory {
private $personTabsFactory;
private $carTabsFactory;
public function injectPersonTabsFactory(IPersonTabsFactory $factory)
{
$this->personTabsFactory = $factory;
}
public function injectCarTabsFactory(ICarTabsFactory $factory)
{
$this->carTabsFactory = $factory;
}
public function create($type) {
switch ($type) {
case 'person':
return $this->personTabsFactory->create();
case 'car':
return $this->carTabsFactory->create();
default:
break;
}
throw new \Exception('Sorry bro! You are not my type. :D');
}
}
presenter mam:
use App\Components\ControlTabsFactory;
class CarsPresenter extends BasePresenter
{
private $controlTabsFactory;
public function __construct(ControlTabsFactory $factory)
{
$this->$controltabsFactory = $factory;
}
protected function createComponentCarTabs()
{
return $this->$controlTabsFactory->create('car');
}
}
--/
a jednotlive interface:
namespace App\Components;
inreface ICarTabsFactory
{
/**
* @return CarTabs
*/
public function create();
}
// to same pro person factory
--/
config:
services:
- App\Components\ControlTabsFactory
- App\Components\ICarTabsFactory
- App\Components\IPersonTabsFactory
jenze pri kazdem pokusu o zavolani o metodu create() to hazi:
Call to a member function create() on a non-object. To znamena, ze ty inject funkce se nezavolaly. Tak to vypada, ze to bunu muset nabusit rucne :D
Editoval marty666 (9. 9. 2014 16:37)
- David Matějka
- Moderator | 6445
- inject metody se volaji defaultne pouze u presenteru, jinde je lepsi pouzit konstruktor
- v presenteru ti pred
controlTabsFactory
prebyva$
- kdyz v presenteru znas ten typ, nebude lepsi do nej injectovat rovnou ICarTabsFactory?
- David Kudera
- Člen | 455
Osobně mi přijde daleko lepší tento způsob komponent.
No a jinak použij ten „inject“ přes konstruktor jako máš v presenteru. To přes inject* metody funguje totiž jen v presenterech a nikde jinde. Jednoduše se vyplatí používat konstruktory vždy ;-)
Edit: hezké, jak na tyto klasické a i docela časté otázky odpoví vždy tolik lidí najednou :-)
Editoval David Kudera (9. 9. 2014 16:45)
- David Matějka
- Moderator | 6445
@Šaman v návodu není chyba, ten používá inject metody pouze u presenteru