Santrauka ir funkcionalumas naudojant sąsajas ir sandarias jungtis

Bandau suprasti, kas iš tiesų apibrėžia kietą nuorodą. Aš perskaičiau temoje esančių pranešimų skaičių, tačiau vienas dalykas vis dar nedera su manimi.

Suprantu, kad klasės turėtų būti įtrauktos į kitas klases, naudojant jų sąsajas, o ne konkrečias jų įgyvendinimo priemones. Aš taip pat suprantu, kad jei klasė seka sąsają, bet kuri klasė, kuri naudoja integruotą sąsają, gali skambinti sąsajoje apibrėžtomis viešosiomis funkcijomis ir tikėtis panašių funkcijų.

 interface iFormatter() { public function format(array $order): array } public class OrderFormatter implements iFormatter { public function format(array $order): array { // ... return $formattedArray; } } public class OrderGenerator implements iGenerator { private $formatter; public function __construct(iFormatter $formatter) { $this->formatter = $formatter; } public function generate() { // ... return $this->formatter->format($order); } } 

Taigi, manau, kad pakeitus tik formatavimą, tai bus apibrėžiama kaip laisvai susieta;

 $example = new OrderGenerator(new CarOrderFormatter); $example->generate(); $example = new OrderGenerator(new VanOrderFormatter); $example->generate(); 

Ką aš visiškai nesuprantu, kai atsisakote atsakomybės viena nuo kitos, tačiau šios klasės vis dar glaudžiai susijusios viena su kita. Kažkas panašaus

 $example = new CarOrderGenerator(new CarOrderFormatter); $example->generate(); $example = new VanOrderGenerator(new VanOrderFormatter); $example->generate(); 

Taip, galite pereiti prie kito generatoriaus, tačiau, žinoma, dažniausiai įvyksta klaida format jei tikisi tam tikrų duomenų iš tam tikros klasės XXXOrderGenerator

Taigi, manau, kad paskutiniame aukščiau pateiktame pavyzdyje aš nukreipiau atsakomybę į savo klases ir, nors ir buvo naudojamos sąsajos, nesu tikras, kad jis vis dar glaudžiai susijęs ar techniškai silpnai sujungtas? Arba, jei visiškai praleidau tašką ...

9
05 мая '17 в 13:31 2017-05-05 13:31 myol nustatytas gegužės 05 '17, 13:31, 2017-05-05 13:31
@ 2 atsakymai

Sakoma, kad klasės yra glaudžiai susijusios viena su kita, kai viena klasė priklauso nuo kito ar priklauso nuo kito vidinio ar specifinio.

Pirmojo pavyzdžio, kurį suteikėte OrderGenerator ir OrderFormatter, atveju jie nėra glaudžiai susieti, nes nė vienas nėra priklausomas nuo kito: jie abu priklauso nuo „iFormatter“. Kitas būdas jį išreikšti: OrderFormatter nieko nežino apie „OrderGenerator“, o „OrderGenerator“ nieko nežino apie „OrderFormatter“, jis tik žino, kad jam perduotas objektas įgyvendina funkciją „formatas“. Jūs tai pabrėžėte, kai perduodate „CarOrderFormatter“ arba „VanOrderFormatter“ į „OrderGenerator“ be neigiamo rezultato.

Antrojo pavyzdžio atveju, kai „CarOrderFormatter“ perduodamas „CarOrderGenerator“, paminėjote, kad atsiras tam tikrų klaidų, kurias pateikėte, pvz., „VanOrderFormatter“ „CarOrderGenerator“. Jei „CarOrderGenerator“ kodas yra pagrįstas „CarOrderFormatter“ įgyvendinimo duomenimis, klasės yra glaudžiai susijusios, nors „iFormatter“ sąsaja yra tai, ką mato „CarOrderGenerator“. Šis kodas bus supainiotas, nes „CarOrderGenerator“ su savo „sutartimi“ sako, kad jam nesvarbu, kuris formatuotojas yra perkeltas, tačiau aišku, ką ji daro. Todėl būtų geriau iš kodų aiškumo, jei „CarOrderGenerator“ aiškiai pasakė, kad galite perduoti „CarOrderFormatter“ tik savo konstruktoriui. Abstrakcija (ty naudojant sąsają) nėra tokia bloga, ir jums reikia galvoti apie tai, kaip turėtų būti apibrėžta sąsaja. Pavyzdžiui, vietoj to, kad turėtumėte tik „iFormatter“ sąsają, jūs turėjote „iCarOrderFormatter“ ir „iVanOrderFormatter“, kurie abu buvo apibrėžti tuo pačiu, tačiau „CarOrderGenerator“ reikalavo „iCarOrderFormatter“, o „VanOrderGenerator“ - iVanOrderFormatter. Jūsų pavyzdys galėtų būti:

 $example = new CarOrderGenerator(new CarOrderFormatter $example->generate(); $example = new CarOrderGenerator(new SportsCarOrderFormatter) $example->generate(); 

arba

 $example = new VanOrderGenerator(new PassengerVanOrderFormatter $example->generate(); $example = new VanOrderGenerator(new CargoVanOrderFormatter) $example->generate(); 

Svarbu suprasti, kad sąsaja yra sukurta siekiant sukurti lankstumą, kuris gali būti perduodamas generatoriui nesukeliant problemų.

6
06 мая '17 в 7:22 2017-05-06 07:22 Atsakymą davė Steve Ellinger gegužės 06 d. 17, 07:22 2017-05-06 07:22

Jūs esate teisus, kad jei susidursite su mašinomis / vonios betonais iGenerator ir iFormatter, jūs tikriausiai turėsite prastą maišymo laiką priklausomybėms. Tačiau faktas yra tas, kad jūs neturėtumėte eiti į šią situaciją, jei tai padarysite, jūs turėtumėte grįžti į piešimo lentą, nes jūs padarėte klaidingą posūkį.

Nežinau, ar jūsų pavyzdys buvo išrastas ar glaudžiai susijęs (ar ne) su jūsų probleminiu domenu. Bet kuriuo atveju problema yra blogas. Jūsų sąsaja turėtų būti atskira atsakomybė arba tikslas. Šiuo tikslu, kas yra iOrderGenerator ir iFormatter tikslas? Jūsų pavyzdyje visi „iOrderGenerator“ yra „iFormatter“. Aš galėčiau pertvarkyti „iOrderGenerator“ iš dizaino, nes tai yra nepraktiška. Problema. Išspręsta.

Na, nepamirškime paprastos išeities ir sakome, kad „iOrderGenerator“ turėjo tikslą. Na, šis tikslas turėtų skirtis nuo „iFormatter“. Jei jūsų sąsajos diegimas viršija vienintelio tikslo ribas arba pakartoja kitos sąsajos tikslą, greičiausiai turėsite blogą dizainą. Pavyzdžiui, galime pasakyti, kad „iFormatter“ tikslas yra spausdinti užsakymus kitaip, priklausomai nuo užsakymo tipo (furgonas ar automobilis). Tada „iOrderGenerator“ yra atsakingas už užsakymų (bet kokio tipo) kūrimą. Bet aš galiu kelis būdus sukurti užsakymą. „CsvOrderGenerator“ arba „XmlOrderGenerator“ arba „BulkOrderGenerator“ (bet niekada „CarOrderGen“ ar „VanOrderGen“).

Pasirinkę „Nit“ jūsų pavyzdyje, galime atkreipti dėmesį į dizaino problemas, kurios paaiškina, kaip susidūrėte su nepatogia situacija bandant parodyti gerą kodo koncepciją.

Jūs iFormatter yra bloga sąsaja, nes ji grąžina neapibrėžtą vertę (masyvą). Viskas, kas naudoja grįžimo vertę, reikalauja gilių žinių apie tai, kaip konkrečiai dirbo, kad žinotų, kurie elementai buvo ar nebuvo įtraukti į masyvą. Ty tarsi aš žinojau, kad yra raktas „OrderId“ reikšmė, neskaitant kodo ar žiūrint į rezultatą (debug / print). Vietoj to, „iFormatter“ turėtų grąžinti fiksuotą gerai aprašytą tipą, ty „CarFormat“ arba „VanFormat“, kurių kiekvienas gali įdiegti „iFormat“, kuris suteikia bendrus prieigos įrenginius užsakymo numeriui ir kainai.

„IOrderGenerator“ turbūt turėtų sukurti „iOrder“. Kas galėtų būti getFormatter metodas: iFormatter.

Šie pakeitimai gali išvalyti dizainą ir nurodyti aiškesnius kiekvieno konkretaus tikslo tikslus, kurie jums nereikės nukreipti į originalą.

1
09 мая '17 в 10:38 2017-05-09 10:38 atsakymą davė Jeremy Giberson gegužės 09 d. 17 d. 10:38 2017-05-09 10:38

Žr. Kitus klausimus apie „ arba užduokite klausimą