Programovanie

Ako nepoužívať rozhrania v C #

Pri navrhovaní aplikácie budete často musieť používať rozhrania a abstraktné triedy. Tento článok pojednáva o niekoľkých bežných príkladoch „zneužitia rozhrania“ a stratégiách, pomocou ktorých sa im môžeme vyhnúť. Diskutuje sa tiež o tom, čo sa myslí pod pojmom „programovať na rozhranie a nie na implementáciu“.

Čo sú to rozhrania?

Najprv si vysvetlíme, aké sú rozhrania a prečo sú pri programovaní potrebné. Rozhranie je výlučne zmluva; nemá žiadnu implementáciu. Rozhranie obsahuje iba deklarácie členov. Môžete mať deklarácie metód, nie však definície. Členovia deklarovaní v rozhraní by mali byť implementovaní v typoch (triedach a štruktúrach), ktoré rozširujú alebo implementujú rozhranie. Rozhranie nemôže obsahovať polia. Rozhranie nemožno serializovať, pretože nemôže obsahovať dátové členy. Ako som už povedal, rozhranie môže mať iba deklarácie a nie definície.

Nerobte zmeny v rozhraniach

Trieda alebo štruktúra, ktorá rozširuje rozhranie, by mala implementovať všetkých svojich členov. Ak sa implementácia zmení, váš kód bude fungovať. Ak sa však zmluva, t. J. Rozhranie, zmení, potom budete musieť zmeniť implementácie všetkých typov, ktoré rozširujú rozhranie. Inými slovami, akákoľvek zmena rozhrania ovplyvní všetky typy, ktoré rozširujú rozhranie. Typy rozširujúce rozhranie sa musia riadiť zmluvou. Rozhrania teda používajte, iba ak ich zriedka potrebujete zmeniť. Spravidla je lepšie vytvoriť nové rozhranie ako zmeniť existujúce.

Programujte na rozhranie, nie na implementáciu

Možno ste niekedy počuli slová „programujte na rozhranie a nie na implementáciu“. Možno ste vo svojom kóde používali rozhrania, ale stále ste programovali implementáciu. Pozrime sa teraz na rozdiel medzi týmito dvoma prístupmi.

Pri programovaní na rozhranie namiesto konkrétnej implementácie používate najobecnejšiu abstrakciu (rozhranie alebo abstraktnú triedu). Pretože rozhrania zaručujú jednotnosť, programovanie rozhrania znamená, že s podobnými objektmi môžete pracovať jednotným spôsobom. Pritom ste oddelení od implementácie - tj. Vaše implementácie sa môžu líšiť. To dodáva flexibilitu aj vašim návrhom.

Nasledujúci úryvok kódu ilustruje programovanie na rozhranie. Zvážte rozhranie s názvom IRepository, ktoré obsahuje deklaráciu niekoľkých metód. Triedy ProductRepository a CustomerRepository rozširujú rozhranie IRepository a implementujú metódy deklarované v rozhraní IRepository, ako je uvedené nižšie.

verejné rozhranie IRepository

    {

// Nejaký kód

    }

verejná trieda ProductRepository: IRepository

    {

// Nejaký kód

    }

verejná trieda CustomerRepository: IRepository

    {

// Nejaký kód

    }

Nasledujúci kód možno použiť na vytvorenie inštancie ProductRepository.

IRepository repository = new ProductRepository ();

Myšlienka je, že tu môžete použiť ľubovoľnú triedu, ktorá implementuje rozhranie IRepository. Platí teda aj nasledujúce vyhlásenie.

IRepository repository = new CustomerRepository ();

Keď naprogramujete implementáciu, táto uniformita sa stratí. Namiesto toho budete zvyčajne mať na kontrolu správania svojho kódu niektoré konštrukty, napríklad príkazy „if..else“ alebo „switch..case“.

Zabráňte nadmernému použitiu rozhraní

Priraďovanie každej triedy k rozhraniu nie je dobrým zvykom. Nadmerné používanie rozhraní týmto spôsobom vytvára zbytočnú zložitosť, zavádza nadbytočnosť kódu, porušuje YAGNI a znižuje čitateľnosť a udržiavateľnosť kódovej základne. Rozhrania sa používajú na zoskupenie objektov, ktoré sa vyznačujú rovnakým správaním. Ak objekty nemajú rovnaké správanie, toto zoskupenie nie je potrebné. Príkladom nadmerného používania rozhraní je použitie rozhraní, keď ho nebudete mať viac implementovaných.

Vytváranie rozhraní pre triedu, ktoré sa zhoduje s verejnými členmi triedy, je úplne bežné. Pritom nepridávate vôbec žiadnu hodnotu - iba duplikujete rozhranie triedy bez pridania akejkoľvek skutočnej abstrakcie.

Pozrime sa teraz na príklad nadmerného používania rozhraní. Zvážte nasledujúce rozhranie s názvom IProduct.

verejné rozhranie IProduct

    {

int Id {get; sada; }

reťazec ProductName {get; sada; }

dvojitá cena {dostať; sada; }

int Množstvo {get; sada; }

    }

Trieda Produkt rozširuje rozhranie IProduct, ako je uvedené nižšie.

verejná trieda Produkt: IProduct

    {

public int Id {get; sada; }

verejný reťazec ProductName {get; sada; }

verejné dvojité Cena {dostať; sada; }

public int Množstvo {get; sada; }

    }

Je zrejmé, že rozhranie IProduct nepotrebujeme, pretože rozhranie a jeho implementácia sú identické. Redundantný kód je zbytočný.

Pozrime sa na ďalší príklad. Nasledujúci úryvok kódu zobrazuje rozhranie s názvom IProductManager, ktoré má deklaráciu dvoch metód, a to Uložiť a Aktualizovať.

 verejné rozhranie IProductManager

    {

void Save (produkt IProduct);

void Update (produkt IProduct);

    }

Rozhranie IProductManager obsahuje vyhlásenia o verejných metódach triedy ProductManager. Takto vyzerá trieda ProductManager.

 verejná trieda ProductManager: IProductManager

    {

public void Save (produkt IProduct)

        {

// Sem napíš svoju implementáciu

        }

public void Update (produkt IProduct)

        {

// Sem napíš svoju implementáciu

        }

    }

Príklady nadmerného používania rozhraní sú rozhrania IProduct a IProductManager. Obe tieto rozhrania majú jednu implementáciu a neprinášajú vôbec žiadnu hodnotu.

Pomocou rozhraní môžete odstrániť nepotrebné spojky v kóde a zabezpečiť, aby bol váš kód ľahko testovateľný. Malo by sa však zabrániť nadmernému použitiu rozhraní. Rozhrania používajte, iba ak bude ich implementácia viac ako jedna. Rozhrania môžete tiež použiť, keď máte triedu, ktorá má veľa rolí alebo má viac povinností. V takom prípade môže vaša trieda implementovať viac rozhraní - jedno pre každú rolu.

$config[zx-auto] not found$config[zx-overlay] not found