Volejte super - Call super
Volejte super je kód vůně nebo anti-vzor některých objektově orientované programování jazyky. Call super je návrhový vzor, ve kterém určitá třída stanoví, že v odvozené podtřídě je uživatel povinen přepsat metodu a zavolat zpět přepsanou funkci samotnou v určitém bodě. Přepsaná metoda může být záměrně neúplná a závisí na přepsané metodě, která předepsaným způsobem rozšíří její funkčnost. Skutečnost, že jazyk sám o sobě nemusí být schopen prosadit všechny podmínky předepsané v této výzvě, však z něj činí anti-vzor.
Popis
V objektově orientovaném programování mohou uživatelé zdědit vlastnosti a chování nadtřídy v podtřídách. Podtřída může přepsat metody své nadtřídy nahrazením vlastní implementace metody implementací nadtřídy. Někdy metoda přepsání zcela nahradí odpovídající funkčnost v nadtřídě, zatímco v jiných případech musí být metoda nadtřídy stále volána z přepisovací metody. Většina programovacích jazyků proto vyžaduje, aby přepisující metoda musela explicitně volat přepsanou metodu v nadtřídě, aby mohla být spuštěna.
Volání super anti-pattern se spoléhá na uživatele rozhraní nebo rozhraní, aby odvodili podtřídu z konkrétní třídy, přepsali určitou metodu a vyžadovali přepsanou metodu pro volání původní metody z přepisující metody:[1]
To je často vyžadováno, protože nadtřída musí provádět některé instalační úkoly, aby třída nebo framework správně fungovaly, nebo protože hlavní úkol nadtřídy (který se provádí touto metodou) je rozšířen pouze podtřídou.
Anti-vzor je požadavek volání rodiče. V reálném kódu existuje mnoho příkladů, kde může metoda v podtřídě stále chtít funkčnost nadtřídy, obvykle tam, kde pouze rozšiřuje nadřazenou funkčnost. Pokud stále musí volat nadřazenou třídu, i když plně nahrazuje funkčnost, je k dispozici anti-vzor.
Lepším přístupem k řešení těchto problémů je místo toho použít vzor metody šablony, kde nadtřída zahrnuje čistě abstraktní metodu, která musí být implementována podtřídami a musí původní metoda volat tuto metodu:[1]
Jazyková variace
Vzhled tohoto anti-vzoru v programech je obvykle proto, že několik programovacích jazyků poskytuje funkci, která smluvně zajistí, že je z odvozené třídy volána super metoda. Jeden jazyk, který tuto vlastnost má, je docela radikálním způsobem BETA. Tato funkce se nachází například omezeným způsobem Jáva a C ++, kde konstruktor podřízené třídy vždy volá konstruktor nadřazené třídy.
Podporované jazyky před a po metody, jako např Společný Lisp (konkrétně Společný systém objektů Lisp ), poskytnout jiný způsob, jak se vyhnout tomuto anti-vzor. Programátor podtřídy může namísto přepsání metody nadtřídy dodat další metodu, která bude provedena před nebo po metodě nadtřídy. Programátor nadtřídy může také určit před, po, a kolem metody, u nichž je zaručeno, že budou provedeny vedle akcí podtřídy.
Příklad
Předpokládejme, že existuje třída pro generování zprávy o inventáři videopůjčovny. Každý konkrétní obchod má jiný způsob vytváření tabulek aktuálně dostupných videí, ale algoritmus pro generování závěrečné zprávy je stejný pro všechny obchody. Rámec, který používá volání super anti-pattern, může poskytnout následující abstraktní třídu (v C# ):
abstraktní třída ReportGenerator { veřejnost virtuální Zpráva CreateReport() { // Generuje obecný objekt sestavy // ... vrátit se Nový Zpráva(...); }}
Očekává se, že uživatel třídy implementuje podtřídu takto:
třída ConcreteReportGenerator : ReportGenerator { veřejnost přepsat Zpráva CreateReport() { // Tabulková data způsobem specifickým pro obchod // ... // Návrh této třídy vyžaduje volání nadřazené funkce CreateReport () na // konec přepsané funkce. Ale všimněte si, že tento řádek může být snadno vynechán, nebo // vrácená sestava mohla být po volání dále upravena, což by narušilo design třídy // a případně také formát zprávy celé společnosti. vrátit se základna.CreateReport(); }}
Preferované rozhraní vypadá takto:
abstraktní třída ReportGenerator { veřejnost Zpráva CreateReport() { Tabelovat(); // Generuje obecný objekt sestavy // ... vrátit se Nový Zpráva(...); } chráněný abstraktní prázdnota Tabelovat();}
Implementace by přepsala tuto třídu takto:
třída ConcreteReportGenerator : ReportGenerator { chráněný přepsat prázdnota Tabelovat() { // Tabulková data způsobem specifickým pro obchod // ... }}