Autor Zpráva
Magnus123
Profil
Ahoj.

Když dělám aplikaci v MVC architektuře, je potřeba mít někdy nějakou třídu, která není potomkem žádné jiné třídy? Pokud bych o nějaké takové třídě uvažoval, byla by to chyba v návrhu, nebo se skutečně může taková třída použít?

Žádný případ mě nenapadá, tak se raději předem zeptám.

Díky moc.
Alphard
Profil
Docela obvyklé je mít každou třídu jako potomka nějaké základní, např. Nette\Object.
PHP umožňuje vytvořit třídu bez předka, některé jiné jazyky ne, implicitně se dědí nejvyšší rodič, který obecně určuje vlastnosti objektu. (Tím nechci říct, že je to dobře jen proto, že je to v jiných jazycích, ale občas je to výhodné.)
Nox
Profil
V MVC vůbec nejde o to, jestli je něco potomkem nějaké třídy, to jsi asi špatně pochopil. Dědičnost sama je spíš pro redukci duplicity.

MVC/P mluví o separaci aplikace na logickou část aplikace (řeší to o čem web je), prezentační část (zobrazí stav uživateli) a kontrolní část, co příjmá požadavky od uživatele, předá je modelu ať to vyřeší a pak předá výsledky do view
(někdo bude možná mít přesnější/lepší definici)

Edit 1:
Takže ano, klidně používej třídy bez rodiče. Mj. máme i skládání, interfacy a další srandy ... nejen z dědictví je živa třída ;)

Edit 2:
Třeba Nette\Object je prostě jen pro nějaké vychytávky, ale tak je to i dobře, třídy které spolu nesouvisí* nemají mít stejného rodiče (pokud neimplementuje takto extrémně obecné prvky). Osobně ani Nette\Object nepoužívám.

Pokud bychom nebrali v potaz Nette\Object, tak naopak myslim že spousta tříd Modelu nebude mít rodiče

*) a nejen to - dědičnost se má použít, pokud ty třídy jsou defakto to samé, jen jde třeba o nějaké specializace a liší se třeba jen v pár věcech. Jinak pro stejnou funkčnost tu jsou interfacy, a pro využití nějakého chování (nenapadá mě dobrá formulace) je kompozice
Joker
Profil
Magnus123:
Viz Nox, nevidím důvod, proč by zrovna MVC vyžadovalo dědění od nějaké třídy.

Třeba u modelu nevidím důvod, proč by jeho třídy musely nezbytně vždycky od něčeho dědit.
View a controllery bývá šikovné podědit, ale šlo by to řešit i přes rozhraní.
Servisní vrstvě taky většinou stačí rozhraní.

A koneckonců, dědění lze nahradit skládáním, takže při stejném návrhu by bylo možné se obejít úplně bez dědění (jakkoli neříkám, že to je správný přístup).
Alphard
Profil
Pokud bychom nebrali v potaz Nette\Object, tak naopak myslim že spousta tříd Modelu nebude mít rodiče
Odkazoval jsem API, právě aby bylo patrné, co se dědí. Osobně to považuji za rozumné, prakticky nikdy nevytvářím třídy, které by neměly nejvyššího předka. PHP neumožňuje vícenásobnou dědičnost (traity vynechme, je to něco jiného), takže hierarchie, kdy má každá třída právě jednoho předka a lze je pomyslně sestavit do grafu, se mi zdá rozumná.

[#1] Magnus123
Kolegové odpovídali spíš prakticky s ohledem na návrh aplikace, ne tak strukturu tříd. Pak často nastane situace, kdy není třeba nic dědit, spíš předat kontejner s nějakými přístupy do databáze a dalšími závislostmi, takže jednoduše

namespace Application\Cokoliv;

class MojeEntita extends Object
{
  public function __construct($diContainer)
  {
  
  }
}
Magnus123
Profil
Děkuji za odpovědi.
S MVC začínám a zatím to mám tak, že View i Controller dědí Model (kvůli databázi). Tak jsem se chtěl zeptat.
Alphard
Profil
Magnus123:
View i Controller dědí Model (kvůli databázi)
K čemu potřebují databázi? Controller ani View rozhodně nejsou funkčním následníkem databáze a nemají ji dědit. Kdyby ji potřebovaly, řeknu dejte tam traity, ale oni ji nemají potřebovat.
ShiraNai7
Profil
Magnus123:
Databáze by měla být např. v dependency injection containeru jako service.
Magnus123
Profil
Pardon, napsal jsem to špatně.
View a Controller dědí Model kvůli metodám, které pracují s databází. Metody jsou v Modelu.
V Controlleru pak zavolám třeba
$this->login($username, $password);
Controller o databázi nic neví, ale zavolá zdědnou metodu login(), která je v Modelu.
_construct
Profil *
Mám za to, že Controller by nemal volať metodu login(), ktorá je v Model-u. O samotný login() by sa mal postarať samotný Model možno už priamo v metode __construct(). Controller iba spracuje vstupy od klienta a pošle požiadavku na Model aby ich uložil do db a nastavuje View. View na základe požiadavky Controller-a rendruje surové dáta z Model-u.
Nox
Profil
Magnus123:

Tak to máš zmotané nejen MVC, ale i OOP - funkcionalitu si nezpřístupňuješ přes dědění, ale kompozicí ... Controller bude mít vazbu na vytvořený objekt(y) ze sekce Model a na něm volá dané metody, ne na sobě


_construct:
V __constructu nedělat ideálně v podstatě nic, pokud možno, je nesmysl aby provedení akce spočívalo jen ve vytvoření instance.
_construct
Profil *
Nox:
Ja to vidím tak, že každé kliknutie u klienta vyvolá akciu a je jedno či ide o prosté načítanie adresára alebo login do db, vždycky sa to deje. Ale máš pravdu dávať login do constructu je extrém. Prakticky login do db by mal byť súčasťou konkrétnej metody v rámci Model-u ktorá rieši zápis do db.
Joker
Profil
Magnus123:
View a Controller dědí Model kvůli metodám, které pracují s databází. Metody jsou v Modelu.
Dědění podle mě není ten správný vztah, kterým toto realizovat.
Resp. view a controller nejsou rozšíření modelu, tak použít dědičnost nedává moc smysl.

Vazby v MVC lze řešit skládáním (jen případně vazba mezi view a controllerem bývá na webu udělaná tak, že URL odkazu ze stránky vede na příslušný controller)
Spectator
Profil
Jen pro upřesnění, je nějaká vyšší souvislost mezi MVC a OOP? Chápu, že se jedná o návrhový vzor, který se v nejčistší formě vytváří pomocí tříd a z nich vytvořených objektů, ale jak jsem se snažil MVC pochopit, tak mám pocit, že to lze udělat i prostým oddělením těchto tří částí v klasickém přístupu.
Nox
Profil
Spectator:
Ano, MVC určitě není vázané na OOP, jde to i bez něj
Magnus123
Profil
Já nevím, jak jinak to řešit. Když budu muset databázi nějak změnit, stačí mi pouze změnit část jedné metody (přesněji konstruktoru) modelu.
Napadlo mě DB spojení mít v traitu, ale předpokládám, že k tomu by nebylo vhodné řešení ho použít.
Nox
Profil
Magnus123:
Akorát přepíšeš $this->login na $user->login (nebo $authenticator->login), nevím jaký na to má vliv databáze...
Spectator
Profil
Nox:
Děkuji za uppřesnění!

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: