Adapter (tervezési minta)
Az oldal jelenlegi verzióját még nem ellenőrizték tapasztalt közreműködők, és jelentősen eltérhet a 2016. március 9-én felülvizsgált
verziótól ; az ellenőrzések 47 szerkesztést igényelnek .
Adapter |
---|
Adapter |
Sablon szerkezet nézet adapter |
Típusú |
szerkezeti |
Célja |
egy nem módosítható objektum funkcióinak használatának megszervezése egy speciálisan kialakított felületen keresztül (egy osztály (vagy több osztály) felületét hozza a kívánt típusú felületre) |
esetekben érvényes |
a rendszer támogatja a szükséges adatokat és viselkedést, de nem megfelelő felülettel rendelkezik. Az Adapter minta legáltalánosabb használata az, amikor egy újonnan definiált vagy már meglévő absztrakt osztályból származó osztályt akarunk létrehozni. |
profik |
- külső osztályok (komponensek, könyvtárak) megvalósításának beágyazása, a rendszer függetlenné válik a külső osztályok interfészétől;
- más külső osztályok használatára való átállás nem igényli magának a rendszernek az átdolgozását, elég egy osztályt megvalósítani Adapter.
|
Kapcsolódó sablonok |
Homlokzat , lakberendező |
Leírása: Tervezési minták |
Igen |
Az Adapter ( angol. Adapter ) egy szerkezeti tervezési minta , amely egy olyan objektum funkcióinak használatának megszervezésére szolgál, amely nem módosítható egy speciálisan létrehozott interfészen keresztül . Más szóval, ez egy olyan szerkezeti tervezési minta, amely lehetővé teszi az inkompatibilis interfésszel rendelkező objektumok együttműködését.
Főbb jellemzők
Kihívás
A rendszer támogatja a szükséges adatokat és viselkedést, de nem megfelelő felülettel rendelkezik.
Megoldás
Az adapter lehetővé teszi egy burkoló osztály [1] létrehozását a szükséges interfésszel.
Tagok
Egy osztály Adapterleképez egy osztályinterfészt Adapteeegy osztályinterfészre Target(amelyet az osztály valósít meg Adapter). Ez lehetővé teszi az objektum számára, hogy úgy Clienthasználja az objektumot Adaptee(az adapteren keresztül Adapter), mintha az az osztály egy példánya lenne Target.
Így hozzáfér az osztály által megvalósított Clientinterfészhez , amely átirányítja a hívást a -ra .
TargetAdapterAdaptee
Következmények
Az Adapter minta lehetővé teszi a meglévő objektumok új objektumstruktúrákba való beillesztését, az interfészeik különbségeitől függetlenül.
Megjegyzések és megjegyzések
Az Adapter minta lehetővé teszi, hogy a tervezési folyamat figyelmen kívül hagyja a meglévő osztályok interfészeinek lehetséges különbségeit. Ha van egy osztály, amely rendelkezik a szükséges metódusokkal és tulajdonságokkal (legalábbis fogalmilag), akkor szükség esetén az Adapter mintával mindig a kívánt formába hozhatja a felületét.
Az Adapterhez közel áll a Homlokzati minta , nem mindig lehet megkülönböztetni az egyiket a másiktól [2] .
Sablon alkalmazása
Az Adapter minta használatának tipikus példája olyan osztályok létrehozása, amelyek egy PHP nyelvi függvény egyetlen interfészéhez vezetnek, amely hozzáférést biztosít különböző DBMS -ekhez [3] .
A probléma megoldása az Adapter sablon használatával az ábrán látható.
Megvalósítás
Egy másik osztályba már meglévő osztály belefoglalása. A befoglaló osztály interfésze az új követelményeknek megfelelően frissül, metódusainak hívásai pedig a benne foglalt osztály metódusainak hívásaivá alakulnak.
A megvalósítás lépései
- Győződjön meg arról, hogy két osztálya nem kompatibilis interfészekkel:
- hasznos szolgáltatás - egy segédprogram osztály, amelyet nem tud megváltoztatni (vagy harmadik féltől származik, vagy más kód attól függ);
- egy vagy több kliens - olyan meglévő alkalmazásosztályok, amelyek a szolgáltatással nem kompatibilisek egy kényelmetlen vagy nem egyező felület miatt.
- Írja le azt a kliens felületet, amelyen keresztül az alkalmazásosztályok használhatják a szolgáltatási osztályt.
- Hozzon létre egy adapterosztályt ennek az interfésznek a megvalósításával.
- Helyezzen el egy mezőt az illesztőben, amely a szolgáltatásobjektumra mutató hivatkozást tárolja. Ezt a mezőt általában az illesztő konstruktorának átadott objektum tölti ki. Egyszerű adaptáció esetén ez az objektum paraméterként átadható az adapter metódusoknak.
- Valamennyi kliens interfész metódust implementálja az adapterben. Az illesztőnek a munka nagy részét a szolgáltatásra kell delegálnia.
- Az alkalmazás csak a kliens felületen keresztül használja az adaptert. Ez megkönnyíti az adapterek cseréjét és hozzáadását a jövőben.
Ruby
Példa
Rubyban
modul AdapterPattern
# Lehetővé teszi az ügyfél számára, hogy nem kompatibilis interfésszel rendelkező Adaptereket használjon Adapters with Target felülettel
# Alkalmazkodó
osztály A Twitter
def twit a "
Twit megjelent" végére helyezi
# Alkalmazkodó
osztály A Facebook
def - bejegyzése
a „Facebook-bejegyzés közzététele”
végére
kerül
#
Célmodul WebServiceInterface
def send_message
emelés NotImplementedError
end
end
# Adapter
osztály A TwitterAdapter
tartalmazza a WebServiceInterface felületet
def inicializál
@webservice = Twitter . új
vég
def send_message
@webservice . tweet
vége
vége
# Adapterosztály
A FacebookAdapter
tartalmazza a WebServiceInterface felületet
def inicializál
@webservice = Facebook . új
vég
def send_message
@webservice . post
end
end
# Ügyfélosztály
Üzenet attr_accessor : webservice
def send
@webservice . send_message
end
end
def self . a run
'=> Adapter'
üzenet = Üzenet . új
üzenetet . webszolgáltatás = TwitterAdapter . új
üzenet . Küld
üzenetet . webszolgáltatás = FacebookAdapter . új
üzenet . Küld
„
véget
” tesz
AdapterPattern . fuss
Java - öröklődés
Java példa (öröklés útján)
// Cél
nyilvános felület Chief
{
public Object makeBreakfast ();
public Object makeLunch ();
public Object makeDinner ();
}
// Adaptee
public class Plumber
{
public Object getScrewNut ()
{ ... }
public Object getPipe ()
{ ... }
public Object getGasket ()
{ ... }
}
// Adapter
public class ChiefAdapter expands Plumber implements Chief {
public
Object makeBreakfast ( )
{
return getGasket ();
}
public Object makeLunch ()
{
return getPipe ();
}
public Object makeDinner ()
{
return getScrewNut ();
}
}
// Client
public class Kliens
{
public static void eat ( Object dish )
{ ... }
public static void main ( String [] args )
{
Chief ch = new ChiefAdapter ();
Tárgytál = ch . _ készítsen reggelit (); eszik ( tál ); edény = ch . készíts ebédet (); eszik ( tál ); edény = ch . makeDinner (); eszik ( tál ); mentőhívás (); } }
Java összetétel
Java példa (kompozíción keresztül)
// Chief.java fájl
nyilvános felület vezető {
public Object makeBreakfast ();
public Object makeDinner ();
public Object makeSupper ();
}
// Plumber.java fájl
public class vízvezeték-szerelő {
public Object getPipe () {
return new Object ();
}
public Object getKey () {
return new Object ();
}
public Object getScrewDriver () {
return new Object ();
}
}
// ChiefAdapter.java fájl
public class ChiefAdapter implementálja a Chief {
privát Vízvezeték- szerelő = új Vízvezeték-szerelő ();
@Override
public Object makeBreakfast () {
return plumber . getkey ();
}
@Override
public Object makeDinner () {
return plumber . getScrewDriver ();
}
@Override
public Object makeSupper () {
return plumber . getPipe ();
}
}
// Client.java fájl
public class kliens {
public static void main ( String [] args ) {
Chief chief = new ChiefAdapter ();
Tárgykulcs = fej . _ makeDinner (); }
}
scala
Scala példa
csomagobjektum adapter { _
object Battlefield {
védett var redTroops : Array [ Troop ] = Array ()
védett var blueTroops : Array [ Troop ] = Array ()
def addTroop ( csapat : Csapat ) : Egység = {
if ( csapat . oldal == "piros" ) {
redTroops :+= csapat
} else if ( csapat . oldal == "kék" ) {
blueTroops :+= csapat
} else {
throw new Exception ( s"Érvénytelen oldal ${ troop . side } for troop ${ troop . name } " )
}
}
def getClosestEnemyTroop ( oldal : String ): Csapat = {
if ( side == "red" ) {
getTroop ( blueTroops )
} else {
getTroop ( redTroops )
}
}
privát def getTroop ( csapatok : Array [ Csapat ]): Csapat = { if
( csapatok . hossz == 0 ) { dob
új Kivétel ( " Nincs elérhető csapat" }
csapatok ( 0 ) }
}
class Csapat (
val oldal : String ,
val név : String ,
val closeFegyver : String ,
val távolságFegyver : String
) {
def move ( irány : Karakterlánc , távolság : Int ): Unit = {
println ( s"A csapat $ neve $ irányt mozog $ távolság yardon " ) }
en _ _ _ _ _ _ _ _ _ _ _ _ _ _
_ _ _ _ _ _
_ _ _ _
_ _ _ _
_ _ _ _ _ _ _ _ _ _ csapathoz $ name " )
}
println ( s"A csapat $ név megtámadja az ellenséges csapatot ${ enemyTroop . name } $ { fegyver } fegyvereikkel " } }
vonás LanceKnightTroopTrait {
def moveForward ( távolság : Int ) : Egység
def attackClosest ( attackType : String ) : Unit
}
class LanceKnightTroop (
override val side : String ,
override val name : String ,
override val closeWeapon : String ,
override val distance Weapon : String
)
kiterjeszti a csapatot ( side , name , closeWeapon , distanceWeapon )
with LanceKnightTroopTrait {
override def moveForward ( távolság : Int ): Egység = {
mozgás ( "előre" , távolság )
}
def attackClosest ( attackType : String ) felülbírálása : Unit = {
attack ( Battlefield . getClosestEnemyTroop ( side ), attackType )
}
}
object AdapterTest extends AbstractTest {
override def run (): Egység = {
val troop = új csapat ( "kék" , "íjászok" , "kard" , "hosszúíj" )
val lanceKnightTroop = new LanceKnightTroop ( "piros" , "Lance Knights" , "csuka" " , számszeríj )
Battlefield . addTroop ( csapat )
Battlefield . addTroop ( lanceKnightTroop )
println ( "Kimenet:" )
lanceKnightTroop . moveForward ( 300 )
lanceKnightTroop . attackClosest ( "close" )
}
}
}
// Kimenet:
// A Troop Lance Knights 300 yardon halad előre
// A Troop Lance Knights megtámadja az ellenséges csapat íjászait csukáikkal
PHP5
Példa
PHP 5 -ben
<?php
class IndependentDeveloper1
{
public function calc ( $a , $b ) {
return $a + $b ;
}
}
class IndependentDeveloper2
{
public function nameIsVeryLongAnduncomfortable ( $a , $b ) {
return $a + $b ;
}
}
interface IAdapter
{
public function sum ( $a , $b );
}
class ConcreteAdapter1 implements IAadapter
{
protected $object ;
public function __construct () {
$this -> object = new IndependentDeveloper1 ();
}
public function sum ( $a , $b ) {
return $this -> object -> calc ( $a , $b );
}
}
class ConcreteAdapter2 implements IAdapter
{
protected $object ;
public function __construct () {
$this -> object = new IndependentDeveloper2 ();
}
public function sum ( $a , $b ) {
return $this -> object -> nameIsVeryLongAndUncomfortable ( $a , $b );
}
}
//egy helyen készítünk egy betonadaptert, majd a
$adapter1 = new ConcreteAdapter1 ();
$adapter2 = új ConcreteAdapter2 ();
/**
* A kódban mindenhol nem közvetlenül használunk osztályokat, hanem az interfészen keresztül
* ez a függvény nem mindegy, hogy melyik osztályt használjuk, mivel az interfészre támaszkodunk
*
* @param IAdapter $adapter
*/
függvény összege ( IAdapter $ adapter ) {
echo $ adapter -> sum ( 2 , 2 );
}
összeg ( $adapter1 );
összeg ( $adapter2 );
PHP5.4
Példa a
PHP 5.4-ben (Trait)
<?php
class SomeClass
{
public function someSum ( $a , $b )
{
return $a + $b ;
}
}
class AnotherClass
{
public function otherSum ( $a , $b )
{
return $a + $b ;
}
}
trait TAdaptee
{
public function sum ( int $a , int $b )
{
$method = $this -> method ;
return $this -> $method ( $a , $b );
}
}
class SomeAdaptee extends SomeClass
{
use TAdaptee ;
privát $method = 'someSum' ;
}
class AnotherAdaptee expands AnotherClass
{
use TAdaptee ;
private $method = 'másikSum' ;
}
$some = new SomeAdaptee ;
$egyéb = new AnotherAdaptee ;
$néhány -> összeg ( 2 , 2 );
$másik -> összeg ( 5 , 2 );
PHP5.4 Compact
Példa
PHP 5.4-ben (Compact)
<?php
trait TAdaptee
{
public function sum ( int $a , int $b )
{
$method = $this -> method ;
return $this -> $method ( $a , $b );
}
}
class SomeClass
{
use TAdaptee ;
privát $method = 'someSum' ;
public function someSum ( $a , $b )
{
return $a + $b ;
}
}
class AnotherClass
{
use TAdaptee ;
private $method = 'másikSum' ;
public function otherSum ( $a , $b )
{
return $a + $b ;
}
}
$some = új SomeClass ;
$egyéb = új AnotherClass ;
$néhány -> összeg ( 2 , 2 );
$másik -> összeg ( 5 , 2 );
JavaScript
JavaScript példa
function Keresés ( szöveg , szó ) {
var text = szöveg ;
var szó = szó ;
ezt . searchWordInText = function () {
return text ;
};
ezt . getWord = function () {
return word ;
};
};
function SearchAdapter ( adaptee ) {
this . searchWordInText = function () {
return 'Ezek a szavak' + adaptee . getWord ()
+ ' szövegben található ' + adaptee . searchWordInText ();
};
};
var search = new Keresés ( "szöveg" , "szavak" );
var searchAdapter = new SearchAdapter ( keresés );
searchAdapter . searchWordInText ();
Python
Példa
Pythonban
class GameConsole :
def create_game_picture ( self ):
'kép a konzolról' visszaadása
osztály Antenna :
def create_wave_picture ( self ):
return 'kép hullámból'
osztály SourceGameConsole ( GameConsole ):
def get_picture ( self ):
return self . Create_game_picture ()
osztály ForrásAntenna ( Antenna ):
def get_picture ( self ):
return self . Create_wave_picture ()
osztály TV :
def __init__ ( self , source ):
self . forrás = forrás
def show_picture ( self ):
önmagát adja vissza . forrás . get_picture ()
g = SourceGameConsole ()
a = SourceAntenna ()
game_tv = TV ( g )
cabel_tv = TV ( a )
print ( game_tv . show_picture ())
print ( cabel_tv . show_picture ())
C# - kompozíció
C# példa (összetétel)
a rendszer használatával ;
névtér adapter
{
class MainApp
{
static void Main ()
{
// Adapter létrehozása és kérés elhelyezése
Target target = new Adapter ();
cél . kérés ();
// Várja meg a felhasználói
konzolt . olvasni ();
}
}
// "Cél"
class Cél
{
public virtual void Kérelem ()
{
Konzol . WriteLine ( "Called TargetRequest()" );
}
}
// "Adapter"
class Adapter : Cél
{
private Adaptee adaptee = new Adaptee ();
public override void Request ()
{
// Esetleg végezzen más munkát
//, majd hívja meg a SpecificRequest
adaptee-t . SpecificRequest ();
}
}
// "Adaptee"
class Adaptee
{
public void SpecificRequest ()
{
Console . WriteLine ( "Called SpecificRequest()" );
}
}
}
C# - öröklődés
C# példa (öröklődés)
a rendszer használatával ;
névtér adapter
{
class MainApp
{
static void Main ()
{
// Adapter létrehozása és kérés elhelyezése
Adapter adapter = new Adapter ();
adapter . kérés ();
// Várja meg a felhasználói
konzolt . olvasni ();
}
}
// "Cél"
interface ITarget
{
public void Kérelem ();
}
// Használhat absztrakt osztályt
// "Adapter"
class Adapter : Adaptee , ITarget
{
public void Request ()
{
// Esetleg végezzen más munkát
//, majd hívja meg a SpecificRequest
SpecificRequest ();
}
}
// "Adaptee"
class Adaptee
{
public void SpecificRequest ()
{
Console . WriteLine ( "Called SpecificRequest()" );
}
}
}
Delphi
Delphi példa
program adapter;
{$APPTYPE CONSOLE}
{$R *.res}
használ
System.SysUtils;
(*A TTarget osztály kliens felhasználói felülete TAdapterként valósult meg*)
(*TAdapter átirányítja a hívást a TAdaptee-ra*)
típus
TTarget = osztály
functionRequest:string; virtuális;
vége;
TAdapte = osztály
függvény SpecificRequest:string;
vége;
TAdapter = osztály (TTcél)
fAdaptee: TAdaptee;
functionRequest:string; felülírás;
konstruktorCreate;
vége;
{ TCél }
függvény TTarget.Request: string;
kezdődik
Eredmény:= 'Called Target Request()';
vége;
{TAdaptee}
function TAdaptee.SpecificRequest: string;
kezdődik
Eredmény:= 'Speciális kérés()';
vége;
{TAadapter}
konstruktor TAdapter.Create;
kezdődik
fAdaptee:= TAdaptee.Create;
vége;
függvény TAdapter.Request: string;
kezdődik
(*Esetleg más munkát is végezhet, és amikor hívja a SpecificRequest*)
Eredmény:= fAdaptee.SpecificRequest;
vége;
var target: TTarget;
kezdődik
próbálja meg
{ TODO -oUser -cConsole Main : Írja be ide a kódot }
(*adapter létrehozása és kérés benyújtása*)
target:= TAdapter.Create;
WriteLn(cél.Kérés);
WriteLn(#13#10+'Nyomja meg bármelyik gombot a folytatáshoz...');
ReadLn;
cél.Ingyenes;
kivéve
E-n: Kivétel igen
Writeln(E.Osztálynév, ': ', E.Üzenet);
vége;
vége.
Jegyzetek
- ↑ A shell és wrapper ( angolul wrapper - a dekorátor szinonimájaként használt) kifejezések jelentésének közelsége néha zavarhoz vezet, és az Adaptert a Dekorátor sablon szinonimájaként definiálják , míg ez két különböző sablon és az utóbbi más feladatot old meg, nevezetesen: többletkötelezettségek objektumhoz kapcsolása.
- ↑ A különbség az, hogy a Homlokzati mintát az interfész egyszerűsítésére tervezték, míg az Adapter mintát arra tervezték, hogy a különböző meglévő interfészek ugyanazt a kívánt megjelenést hozzák.
- ↑ A PHP nyelv elavult verzióiban a DBMS-hez való hozzáférést függvénykészletként valósítják meg, minden DBMS-nek más neve van, és néha eltérő paraméterkészletet használnak, ami jelentős problémákhoz vezet az egyik DBMS-ről való váltáskor. egy másikat, ha az Adapter sablon segítségével előre nem biztosítanak ilyen átmenetet.
Irodalom
- Alan Shalloway, James R. Trott. Tervezési minták. Az objektum-orientált tervezés új megközelítése = Design Patterns Explained: Új perspektíva az objektum-orientált tervezéshez. - M . : "Williams" , 2002. - S. 288. - ISBN 0-201-71594-5 .
- E. Gamma, R. Helm, R. Johnson, J. Vlissides . Objektumorientált tervezés technikái. Tervezési minták = Design Patterns: Az újrafelhasználható objektum-orientált szoftver elemei. - Szentpétervár. : "Péter" , 2007. - S. 366. - ISBN 978-5-469-01136-1 . ( ISBN 5-272-00355-1 is )
- Eric Freeman, Elizabeth Freeman. Tervezési minták = Head First Design Patterns. - Szentpétervár. : Péter, 2011. - 656 p. - ISBN 978-5-459-00435-9 .
Linkek