Programování

Jak nepoužívat rozhraní v C #

Při navrhování aplikace budete často muset použít rozhraní a abstraktní třídy. Tento článek pojednává o několika běžných příkladech „zneužití rozhraní“ a strategiích, kterými se jim můžeme vyhnout. Rovněž pojednává o tom, co se rozumí pod pojmem „program na rozhraní a ne na implementaci“.

Co jsou to rozhraní?

Nejprve se seznámíme s rozhraními a s tím, proč jsou v programování potřebná. Rozhraní je přísně smlouva; nemá žádnou implementaci. Rozhraní obsahuje pouze deklarace členů. Můžete mít deklarace metod, ale ne definice. Členové deklarovaní v rozhraní by měli být implementováni v typech (třídách a strukturách), které rozšiřují nebo implementují rozhraní. Rozhraní nemůže obsahovat pole. Rozhraní nelze serializovat, protože nemůže mít datové členy. Jak jsem řekl, rozhraní může mít pouze deklarace a ne definice.

Neprovádějte změny rozhraní

Třída nebo struktura, která rozšiřuje rozhraní, by měla implementovat všechny své členy. Pokud se implementace změní, váš kód bude i nadále fungovat. Pokud se však smlouva, tj. Rozhraní, změní, budete muset změnit implementace všech typů, které rozšiřují rozhraní. Jinými slovy, jakákoli změna rozhraní ovlivní všechny typy, které rozšiřují rozhraní. Typy rozšiřující rozhraní musí dodržovat smlouvu. Rozhraní tedy používejte pouze tehdy, když je zřídka potřebujete změnit. Obecně je také lepší vytvořit nové rozhraní než změnit stávající.

Programujte na rozhraní, nikoli na implementaci

Možná jste někdy slyšeli slova „programujte na rozhraní a ne na implementaci“. Možná jste ve svém kódu používali rozhraní, ale stále jste programovali implementaci. Podívejme se nyní na rozdíl mezi těmito dvěma přístupy.

Když programujete na rozhraní, použijete místo konkrétní implementace nejobecnější abstrakci (rozhraní nebo abstraktní třídu). Vzhledem k tomu, že rozhraní zaručují jednotnost, programování na rozhraní znamená, že můžete podobné objekty zpracovávat jednotným způsobem. Přitom jste odděleni od implementace - tj. Vaše implementace se mohou lišit. To dodává vašim návrhům flexibilitu.

Následující fragment kódu ukazuje programování na rozhraní. Zvažte rozhraní s názvem IRepository, které obsahuje deklaraci několika metod. Třídy ProductRepository a CustomerRepository rozšiřují rozhraní IRepository a implementují metody deklarované v rozhraní IRepository, jak je znázorněno níže.

veřejné rozhraní IRepository

    {

// Nějaký kód

    }

veřejná třída ProductRepository: IRepository

    {

// Nějaký kód

    }

veřejná třída CustomerRepository: IRepository

    {

// Nějaký kód

    }

Následující kód lze použít k vytvoření instance ProductRepository.

IRepository repository = new ProductRepository ();

Myšlenka je, že zde můžete použít libovolnou třídu, která implementuje rozhraní IRepository. Platí tedy i následující prohlášení.

IRepository repository = new CustomerRepository ();

Když naprogramujete implementaci, tato uniformita se ztratí. Místo toho obvykle budete mít pro ovládání chování v kódu nějaké konstrukty, například příkazy „if..else“ nebo „switch..case“.

Vyvarujte se nadměrného používání rozhraní

Přidružení každé třídy k rozhraní není dobrým postupem. Nadměrné používání rozhraní tímto způsobem vytváří zbytečnou složitost, zavádí redundanci kódu, porušuje YAGNI a snižuje čitelnost a udržovatelnost kódové základny. Rozhraní se používají ke seskupení objektů, které mají stejné chování. Pokud objekty nemají stejné chování, není nutné toto seskupení. Příkladem nadužívání rozhraní je použití rozhraní, když ho nebudete mít více implementací.

Vytvoření rozhraní pro třídu, která odpovídá veřejným členům třídy, je docela běžné. Přitom nepřidáváte vůbec žádnou hodnotu - pouze duplikujete rozhraní třídy bez přidání skutečné abstrakce.

Podívejme se nyní na příklad, jak jsou rozhraní nadměrně používána. Zvažte následující rozhraní s názvem IProduct.

veřejné rozhraní IProduct

    {

int Id {get; soubor; }

řetězec ProductName {get; soubor; }

dvojnásobná cena {get; soubor; }

int Množství {get; soubor; }

    }

Třída Product rozšiřuje rozhraní IProduct, jak je znázorněno níže.

veřejná třída Produkt: IProduct

    {

public int Id {get; soubor; }

veřejný řetězec ProductName {get; soubor; }

public double Cena {get; soubor; }

public int Množství {get; soubor; }

    }

Je zřejmé, že rozhraní IProduct nepotřebujeme, protože rozhraní a jeho implementace jsou identické. Redundantní kód je zbytečný.

Podívejme se na další příklad. Následující fragment kódu ukazuje rozhraní s názvem IProductManager, které má deklaraci dvou metod, jmenovitě Save and Update.

 veřejné rozhraní IProductManager

    {

void Save (produkt IProduct);

void Update (produkt IProduct);

    }

Rozhraní IProductManager obsahuje deklarace veřejných metod třídy ProductManager. Takto vypadá třída ProductManager.

 veřejná třída ProductManager: IProductManager

    {

public void Save (produkt IProduct)

        {

// Sem napište svoji implementaci

        }

public void Update (produkt IProduct)

        {

// Sem napište svoji implementaci

        }

    }

Rozhraní IProduct a IProductManager jsou příklady nadužívání rozhraní. Obě tato rozhraní mají jedinou implementaci a nepřidávají vůbec žádnou hodnotu.

Pomocí rozhraní můžete odstranit zbytečná propojení v kódu a váš kód snadno otestovat. Je však třeba se vyhnout nadužívání rozhraní. Rozhraní používejte pouze v případě, že bude implementována více než jedna. Rozhraní můžete také použít, když máte třídu, která má mnoho rolí, nebo kterou má více povinností. V tomto případě může vaše třída implementovat více rozhraní - jedno pro každou roli.

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