Propojení obecné a specifické fasády s komponentou

roman.campula
Člen | 60
+
0
-

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
+
0
-

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.