Propojení obecné a specifické fasády s komponentou
- roman.campula
- Člen | 60
Zdravím,
lámu si hlavu s vytvořením následující funkcionality:
- budu mít třídu pro obecnou práci s jakoukoliv tabulkou v DB
- budu mít třídu se specifickými funkcemi, např. vyhledání administrátorů v tabulce users
- budu mít třídu (např. komponentu, presenter apod.), kde budu používat jak obecné, tak speciální funkce
Vymyslel jsem, že „specifická“ třída bude dědit od té „obecné“ třídy. V komponentě nebo presenteru se pak „specifická“ třída přidá přes konstruktor.
V „obecné“ třídě BaseDatabaseFunctions se udržuje, s jakou se pracuje databází a s jakou tabulkou. Dále jsou uvedeny metody, které jsou obecné pro práci s jakoukoliv tabulkou (abych pak nemusel jednu věc měnit na 30 místech).
Ve „specifické“ třídě TestFacade se nastaví, o jakou jde databázi a tabulku. Dále jsou uvedeny metody, které jsou specifické pro danou činnost (např. pro práci s uživateli).
V komponentě nebo presenteru se pak jen předá v konstruktoru TestFacade.
Problémy/dotazy:
- Je správné, že používám dědičnost? Není lepší si předat závislost jen pomocí konstruktoru?
- Pokud tedy používám dědičnost, tak aby se zavolal konstruktor
v BaseDatabaseFunctions, musím mít v TestFacade
parent::__construct()
. To však vyžaduje dva parametry, ale já chci, aby se ideálně dotáhly závislosti sami. - Pokud bych používal předání závislostí v konstruktoru (bez
dědičnosti), pak se mi v komponentě asi nepodaří jednoduše volat obecné
i specifické funkce pomocí
$testFacade->getAll()
i$testFacade->Administrators()
, protože každá metoda bude v jiné třídě.
Díky za posunutí, jakým směrem bych měl jít.
Pozn.: kód není úplně funkční, zjednodušeno pro tento dotaz na fóru
class BaseDatabaseFunctions {
use Nette\SmartObject;
private $databaseContext;
private $databaseTable;
private $database1;
private $database2;
function __construct(AppModule\Model\Database1 $database1,
AppModule\Model\Database2 $database2) {
$this->database1 = $database1;
$this->database2 = $database2;
}
// dle parametru vybere databazi
function setDatabase($databaseName) {
if ($databaseName === "db1") {
$this->databaseContext = $this->database1->getContext();
}
else if ($databaseName === "db2") {
$this->databaseContext = $this->database2->getContext();
}
}
// dle parametru vybere tabulku
function setDatabaseTable($databaseTable) {
$this->databaseTable = $databaseTable;
}
// obecne funkce pro praci s kazdou databazovou tabulkou
function getAll() {
$records = $this->databaseContext->table($this->databaseTable);
return $records;
}
// function getFirst() {}
// function getLast() {}
// function insert() {}
// function update() {}
}
class TestFacade extends BaseDatabaseFunctions {
use Nette\SmartObject;
const DATABASE = "web";
const TABLE = "users";
function __construct() {
parent::__construct(); // two parameters required
$this->setDatabase(self::DATABASE);
$this->setDatabaseTable(self::TABLE);
}
// specialni funkce pro tuto TestFacade
function getAdministrators() {
}
}
class TestControl {
private $testFacade;
function __construct(TestFacade $testFacade) {
$this->testFacade = $testFacade;
}
function allUsers() {
$users = $this->testFacade->getAll(); // obecna funkce
}
function allAdministrators() {
$users = $this->testFacade->getAdministrators(); // specialni funkce
}
}
- Phalanx
- Člen | 310
Ahoj, používám to takto:
<?php
// abstraktni trida je jen takova obalka s funkcema
abstract class CMS_Table
{
use SmartObject;
/** @var Context */
protected $database;
/** @var string */
protected $table;
// bez konstruktoru - jde o abstract class
// a pak tu mám funkce jako např.
public function getSource()
{
if ($this->use_deleted) {
return $this->database->table($this->table)->where('deleted IS NULL');
}
return $this->database->table($this->table);
}
// insert()
// update()
}
// a od toho si dále dědím všechny modely, závislosti (tj. i databázi pro tento model) si předávám v config.neon
class CMS_User extends CMS_Table
{
/** @var string table name */
protected $table = 'cms_auth_user';
/** @var \Nette\Database\Context */
protected $database;
public function __construct(
\Nette\Database\Context $database
) {
$this->database = $database;
}
}
?>
Při přidání nebo odebrání databáze budeš muset měnit související kód všude. U mého návrhu jen v configu.