Ohjelmointi

Kuinka ei käytetä rajapintoja C #: ssä

Suunnitellessasi sovellusta joudut usein käyttämään rajapintoja ja abstrakteja luokkia. Tässä artikkelissa käsitellään joitain yleisiä esimerkkejä "käyttöliittymän väärinkäytöstä" ja strategioita, joita voimme käyttää niiden välttämiseksi. Siinä keskustellaan myös siitä, mitä käsitteellä tarkoitetaan "ohjelmoida käyttöliittymälle eikä toteutukselle".

Mitä rajapinnat ovat?

Ensinnäkin, tutustutaan käyttöliittymiin ja miksi niitä tarvitaan ohjelmoinnissa. Käyttöliittymä on ehdottomasti sopimus; sitä ei ole toteutettu. Käyttöliittymä sisältää vain jäsenilmoitukset. Sinulla voi olla metodideklaraatioita, mutta ei määritelmiä. Rajapinnassa ilmoitetut jäsenet tulisi toteuttaa sellaisissa tyypeissä (luokissa ja rakenteissa), jotka laajentavat tai toteuttavat rajapintaa. Liitäntä ei voi sisältää kenttiä. Käyttöliittymää ei voida sarjata, koska sillä ei voi olla datajäseniä. Kuten sanoin, käyttöliittymässä voi olla vain ilmoituksia eikä määritelmiä.

Vältä muutoksia rajapintoihin

Luokan tai rakenteen, joka laajentaa käyttöliittymää, tulisi toteuttaa kaikki sen jäsenet. Jos toteutus muuttuu, koodisi toimii edelleen. Jos sopimus eli käyttöliittymä kuitenkin muuttuu, sinun on muutettava kaiken tyyppisiä käyttöliittymää laajentavia toteutuksia. Toisin sanoen kaikki muutokset käyttöliittymään vaikuttavat kaikkiin tyyppeihin, jotka laajentavat käyttöliittymää. Rajapinnan laajentavien tyyppien on noudatettava sopimusta. Joten käytä liitäntöjä vain silloin, kun sinun on harvoin tarpeen vaihtaa niitä. Lisäksi on yleensä parempi luoda uusi käyttöliittymä kuin muuttaa olemassa olevaa käyttöliittymää.

Ohjelmoi käyttöliittymään, ei toteutukseen

Olet ehkä kuullut sanat "ohjelma käyttöliittymälle eikä toteutukselle" silloin tällöin. Olet ehkä käyttänyt rajapintoja koodissasi, mutta ohjelmoit edelleen toteutukseen. Tarkastellaan nyt näiden kahden lähestymistavan välistä eroa.

Kun ohjelmoit käyttöliittymälle, käytät yleisintä abstraktiota (käyttöliittymä tai abstrakti luokka) konkreettisen toteutuksen sijaan. Koska rajapinnat takaavat yhdenmukaisuuden, ohjelmointi käyttöliittymälle tarkoittaa, että voit käsitellä samankaltaisia ​​esineitä yhtenäisellä tavalla. Tällöin olet irrotettu toteutuksesta - toisin sanoen toteutuksesi voivat vaihdella. Tämä lisää joustavuutta myös malleihisi.

Seuraava koodinpätkä kuvaa ohjelmointia käyttöliittymälle. Harkitse IRepository-nimistä käyttöliittymää, joka sisältää muutaman menetelmän ilmoituksen. ProductRepository- ja CustomerRepository-luokat laajentavat IRepository-rajapintaa ja toteuttavat IRepository-rajapinnassa ilmoitetut menetelmät, kuten alla on esitetty.

julkinen käyttöliittymä IR-varasto

    {

// Joitakin koodeja

    }

public class ProductRepository: IR-varasto

    {

// Joitakin koodeja

    }

public class CustomerRepository: IR-varasto

    {

// Joitakin koodeja

    }

Seuraavaa koodia voidaan käyttää ProductRepository-ilmentymän luomiseen.

IRepository repository = uusi ProductRepository ();

Ajatuksena on, että voit käyttää mitä tahansa luokkaa, joka toteuttaa IRepository-käyttöliittymän. Joten seuraava lausuma on myös pätevä.

IRepository repository = uusi CustomerRepository ();

Kun ohjelmoit toteutukseen, tämä yhtenäisyys menetetään. Sen sijaan sinulla on tyypillisesti joitain rakenteita, kuten "if..else" tai "switch..case" -lausekkeet koodin käyttäytymisen hallitsemiseksi.

Vältä liitäntöjen liikakäyttöä

Jokaisen luokan liittäminen käyttöliittymään ei ole hyvä käytäntö. Rajapintojen liiallinen käyttö tällä tavalla aiheuttaa tarpeetonta monimutkaisuutta, tuo koodin redundanssin, rikkoo YAGNI: ta ja vähentää koodipohjan luettavuutta ja ylläpidettävyyttä. Liitäntöjä käytetään ryhmittelemään objektit, joilla on identtinen käyttäytyminen. Jos kohteilla ei ole samanlaista käyttäytymistä, ryhmittelyä ei tarvita. Käyttöliittymien käyttö silloin, kun sitä ei ole tarkoitus toteuttaa useita kertoja, on esimerkki käyttöliittymän liikakäytöstä.

Rajapinnan luominen luokalle, joka vastaa luokan julkisia jäseniä, on melko yleistä. Tällöin et lisää mitään arvoa - vain kopioit luokan käyttöliittymän lisäämättä mitään todellista abstraktiota.

Tarkastellaan nyt esimerkkiä siitä, miten rajapintoja käytetään liikaa. Harkitse seuraavaa käyttöliittymää nimeltä IProduct.

julkisen käyttöliittymän IP-tuote

    {

int Id {get; aseta; }

merkkijono ProductName {get; aseta; }

kaksinkertainen hinta {get; aseta; }

int Määrä {get; aseta; }

    }

Tuoteluokka laajentaa IProduct-käyttöliittymää alla olevan kuvan mukaisesti.

julkinen luokka Tuote: IP-tuote

    {

julkinen int Id {get; aseta; }

julkinen merkkijono ProductName {get; aseta; }

julkinen kaksinkertainen hinta {get; aseta; }

public int Määrä {get; aseta; }

    }

Emme selvästikään tarvitse IProduct-käyttöliittymää, koska käyttöliittymä ja sen toteutus ovat identtiset. Redundantti koodi on tarpeeton.

Katsotaanpa toista esimerkkiä. Seuraava koodinpätkä näyttää käyttöliittymän nimeltä IProductManager, jolla on kaksi tapaa, nimittäin Tallenna ja Päivitä.

 julkinen käyttöliittymä IProductManager

    {

void Save (IP-tuote);

void Update (IProduct-tuote);

    }

IProductManager-käyttöliittymä sisältää ProductManager-luokan julkisten menetelmien ilmoitukset. Täältä näyttää ProductManager-luokka.

 julkisen luokan ProductManager: IProductManager

    {

public void Save (IP-tuote)

        {

// Kirjoita toteutus tähän

        }

public void Update (IP-tuote)

        {

// Kirjoita toteutus tähän

        }

    }

IProduct- ja IProductManager-liitännät ovat esimerkkejä käyttöliittymän liiallisesta käytöstä. Molemmilla käyttöliittymillä on yksi toteutus, eivätkä ne tuota mitään arvoa.

Liitäntöjen avulla voit poistaa tarpeettomat kytkennät koodistasi ja tehdä koodistasi helposti testattavan. Rajapintojen liiallista käyttöä tulisi kuitenkin välttää. Käytä rajapintoja vain, kun niitä on useampi kuin yksi. Voit käyttää rajapintoja myös silloin, kun sinulla on luokka, jolla on useita rooleja tai joilla on useita vastuita. Tässä tapauksessa luokkasi voi toteuttaa useita rajapintoja - yhden kutakin roolia varten.