Princip for adskillelse af grænseflade i Java

1. Introduktion

I denne vejledning diskuterer vi Interface Segregation Principle, et af SOLID-principperne. Ved at repræsentere “jeg” i “SOLID” betyder adskillelse af grænseflade simpelthen, at vi skal bryde større grænseflader i mindre.

Således sikres det, at implementeringsklasser ikke behøver at implementere uønskede metoder.

2. Princip for grænsefladeseparation

Dette princip blev først defineret af Robert C. Martin som: “Klienter bør ikke tvinges til at være afhængige af grænseflader, de ikke bruger“.

Målet med dette princip er at reducere bivirkningerne ved at bruge større grænseflader ved at opdele applikationsgrænseflader i mindre. Det svarer til Single Responsibility Principle, hvor hver klasse eller interface tjener et enkelt formål.

Præcis applikationsdesign og korrekt abstraktion er nøglen bag princippet om grænsefladeseparation. Selvom det tager mere tid og kræfter i designfasen af ​​en applikation og muligvis øger kodens kompleksitet, i sidste ende får vi en fleksibel kode.

Vi vil se på nogle eksempler i de senere afsnit, hvor vi overtræder princippet, og så løser vi problemet ved at anvende princippet korrekt.

3. Eksempel på interface og implementering

Lad os se på en situation, hvor vi har en Betaling interface brugt af en implementering Bankbetaling:

offentlig grænseflade Betaling {void initiatePayments (); Objektstatus (); Liste getPayments (); }

Og implementeringen:

offentlig klasse BankPayment implementerer betaling {@Override public void initiatePayments () {// ...} @Override public Object status () {// ...} @Override public List getPayments () {// ...}}

Lad os for enkelheds skyld ignorere den faktiske forretningsimplementering af disse metoder.

Dette er meget klart - indtil videre implementeringsklassen Bankbetaling har brug for alle metoderne i Betaling interface. Således overtræder det ikke princippet.

4. Forurening af grænsefladen

Når vi bevæger os fremad i tiden, og flere funktioner kommer ind, er der behov for at tilføje en LånBetaling service. Denne service er også en slags Betaling men har et par flere operationer.

For at udvikle denne nye funktion vil vi tilføje de nye metoder til Betaling grænseflade:

offentlig grænseflade Betaling {// originale metoder ... ugyldig intiateLoanSettlement (); ugyldig initiateRePayment (); }

Dernæst har vi den LånBetaling implementering:

offentlig klasse LoanPayment implementerer Payment {@Override public void initiatePayments () {throw new UnsupportedOperationException ("Dette er ikke en bankbetaling"); } @Override public Objektstatus () {// ...} @Override public List getPayments () {// ...} @Override public void intiateLoanSettlement () {// ...} @Override public void initiateRePayment () {// ...}}

Nu, siden Betaling interface er ændret, og flere metoder blev tilføjet, alle implementeringsklasser skal nu implementere de nye metoder. Problemet er, at implementeringen er uønsket og kan føre til mange bivirkninger. Her, den LånBetaling implementeringsklasse skal implementere initiatePayments () uden noget reelt behov for dette. Og så krænkes princippet.

Så hvad sker der med vores Bankbetaling klasse:

offentlig klasse BankPayment implementerer betaling {@Override public void initiatePayments () {// ...} @Override public Object status () {// ...} @Override public List getPayments () {// ...} @Override public void intiateLoanSettlement () {throw new UnsupportedOperationException ("Dette er ikke en lånebetaling"); } @Override public void initiateRePayment () {throw new UnsupportedOperationException ("Dette er ikke en lånebetaling"); }}

Bemærk, at Bankbetaling implementering har nu implementeret de nye metoder. Og da det ikke har brug for dem og ikke har nogen logik for dem, er det det bare kaste en Ikke-understøttetOperationException. Det er her, vi begynder at krænke princippet.

I det næste afsnit vil vi se, hvordan vi kan løse dette problem.

5. Anvendelse af princippet

I det sidste afsnit har vi bevidst forurenet grænsefladen og overtrådt princippet. I dette afsnit undersøger vi, hvordan du tilføjer den nye funktion til lånebetaling uden at krænke princippet.

Lad os nedbryde grænsefladen for hver betalingstype. Den nuværende situation:

Bemærk i klassediagrammet, og henvis til grænsefladerne i det tidligere afsnit, at status () og getPayments () der kræves metoder i begge implementeringer. På den anden side, initiatePayments () kræves kun i Bankbetaling, og initiateLoanSettlement () og initiateRePayment () metoder er kun til LånBetaling.

Med det sorteret, lad os bryde grænsefladerne op og anvende princippet om adskillelse af grænseflade. Således har vi nu en fælles grænseflade:

offentlig grænseflade Betaling {Objektstatus (); Liste getPayments (); }

Og to grænseflader til de to typer betalinger:

offentlig grænseflade Bank udvider betaling {ugyldig initiatePayments (); }
offentlig grænseflade Lån udvider betaling {void intiateLoanSettlement (); ugyldig initiateRePayment (); }

Og de respektive implementeringer, begyndende med Bankbetaling:

offentlig klasse BankPayment implementerer Bank {@Override public void initiatePayments () {// ...} @Override public Object status () {// ...} @Override public List getPayments () {// ...}}

Og endelig vores reviderede LånBetaling implementering:

offentlig klasse LoanPayment implementerer lån {@Override public void intiateLoanSettlement () {// ...} @Override public void initiateRePayment () {// ...} @Override public Object status () {// ...} @Override offentlig liste getPayments () {// ...}}

Lad os nu gennemgå det nye klassediagram:

Som vi kan se, er grænsefladerne ikke i strid med princippet. Implementeringerne behøver ikke at give tomme metoder. Dette holder koden ren og reducerer risikoen for fejl.

6. Konklusion

I denne vejledning så vi på et simpelt scenarie, hvor vi først afveg fra at følge Interface Segregation Princip og så de problemer, denne afvigelse forårsagede. Derefter viste vi, hvordan man anvender princippet korrekt for at undgå disse problemer.

Hvis vi har at gøre med forurenede ældre grænseflader, som vi ikke kan ændre, kan adaptermønsteret være nyttigt.

Princippet om grænsefladesegregering er et vigtigt koncept under design og udvikling af applikationer. Overholdelse af dette princip hjælper med at undgå oppustede grænseflader med flere ansvarsområder. Dette hjælper os til sidst også med at følge princippet om et enkelt ansvar.

Som altid er koden tilgængelig på GitHub.


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