Možnost trait místo dědění

kolibla
Člen | 22
+
0
-

Ahoj,

v aktuální formě máme:

abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    // další funkcionalita
}

Byla bych ráda, abych mohla poté všude jinde používat místo této konstrukce:

final class MyPresenter extends BasePresenter
{
	// další funkcionalita
}

tak používat pěkně traity:

final class MyPresenter
{
    trait BasePresenter;

	// další funkcionalita
}

Je možné? V tuto chvíli mi to nejde, protože BasePresenter není traita.

Děkuji.

Šaman
Člen | 2528
+
+1
-

Můžeš mít

final class MyPresenter extends Nette\Application\UI\Presenter
{
   trait BasePresenter;

   // další funkcionalita
}

Nebo proč nechceš dědit od Nette Presenteru?
A co u komponent nebo response?

Editoval Šaman (20. 1. 18:17)

kolibla
Člen | 22
+
0
-

Špatně si mě pochopil. Od hlavního Nette Presenteru chci dědit, chci využívat ty vlastnosti – dokonce si myslím, že to dědění lze nějak zapsat do Traity. Takže závěr je takový, že BasePresenter bude Traita, takže něco jako BaseTrait a tu BaseTraitu pak budu používat v dalších WhateverPresenter.

Ta hlavní myšlenka je taková, že bych chtěla BasePresenter eliminovat, je to skoro antipatern. BaseTraita nebude představovat jeden hlavní objekt… Výhodou toho všeho právě je, že bude hodně Trait, které budou využívat Presentery, například:

final class MyFirstPresenter
{
    trait WhatEverTrait1;
	trait WhatEverTrait2;

	// další funkcionalita
}

final class MySecondPresenter
{
    trait WhatEverTrait1;
	trait WhatEverTrait3;

	// další funkcionalita
}

Ale každá tato traita musí mít vlastnosti hlavního Nette Presenteru logicky.

Rozumíme si?

Editoval kolibla (20. 1. 18:32)

Šaman
Člen | 2528
+
0
-

kolibla napsal(a):

Ale každá tato traita musí mít vlastnosti hlavního Nette Presenteru logicky.

Rozumíme si?

Asi ne. Jak to chceš zajistit (že každá traita musí mít vlastnosti Presenteru)?

Tvůj presenter JE Nette Presenter, tak by od něho měl dědit.
Traity by myslím měly základní chování upravovat, ideálně nezávisle na sobě. Takže věci, které mám v BasePresenteru bych asi byl schopný přepsat do trait: TSecured, TMyTemplateFileFinding, TAdminModule apod. Ale tím, že Presenter bude vždy instance Nette Presenteru, tak ti přece nic nebrání opravdu dědit.

Jestli je možné přepsat Presenter na traitu, to si nejsem jistý. Trochu předpokládám různé interní nette podmínky if ($obj instanceof UI\Presenter), které by s traitou nebyly splněné. Ale to už jen přemýšlím nahlas, neber to jako něco ověřeného.

Přesto bych se snažil nejprve jít tradiční cestou, tedy základní Presenter dědit a pomocí různých zaměnitelných trait si upravit chování konkrétních věcí. Řekl bych, že si ušetříš mnoho potenciálních záseků, protože zrovna Presenter je v samotném jádru hlavního modulu Nette Application.

Editoval Šaman (20. 1. 18:48)

kolibla
Člen | 22
+
0
-

Já si naopak myslím, že by to dle toho schématu mělo jít, protože hlavní princip má být:

parent > trait > child

Zkusíme ještě někoho, jak se k tomu vyjádří. Zkrátka dědičnost se mi v tomto kontextu nelíbí, Traita se dá kvalifikovat jako určitá (multi) kompozice.

Editoval kolibla (20. 1. 18:57)

Šaman
Člen | 2528
+
0
-

Jasný, sám jsem zvědavý na názor ostatních. A hlavně @DavidGrudl, protože on asi nejvíc ví co by to udělalo v jádru Nette Application.

MajklNajt
Člen | 371
+
0
-

Písala si, že od Nette\Application\UI\Presenter chceš dediť, tak potom to, čo písal Šaman je presne to, čo hľadáš, a čo nie je antipattern

Kamil Valenta
Člen | 333
+
+5
-

kolibla napsal(a):

Já si naopak myslím, že by to dle toho schématu mělo jít, protože hlavní princip má být:

parent > trait > child

To ani ne, ten nákres by spíš měl být nějak takto:

parent > child
           |
         trait

Traity do řetězce dědění nevstupují. Jen přidávají potřebné metody do classy, kde definovány nejsou.

mkoula
Generous Backer | 43
+
+3
-

BasePresenter je Presenter a dědí se, není to traita. Jde o to, co je v něm a jestli to opravdu všechno musí být ve všech ostatních Presenterech, které ho dědí. Podívej se na video 33.3 novinek v Nette 3 (https://www.youtube.com/watch?…), kde to David vysvětluje.

Jde o to skutečně rozdělit věci do Trait, podle nějaké interní logiky. Základem pak je Traita, která ti nadefinuje, co je potřeba a má i metodu ->injectTraitName(), ve které můžeš zavolat věci, které se mají spustit v rámci ne konstruktoru, ale startup() metody daného presenteru:

$this->onStartup[] = function () {
// do something
};

To dá možnost mít rozdělený a čitelnější kód…