când creați software, este util să înțelegeți o gamă largă de principii de proiectare. Înțelegerea modului de proiectare a unui sistem cu cel mai potrivit principiu poate salva nenumărate ore de dezvoltare și dureri de cap.

să vorbim mai întâi despre moștenire pentru un pic. Moștenirea este atunci când o clasă moștenește starea și/sau comportamentul de la o clasă părinte. Să presupunem că proiectăm un joc și am nevoie de un câine:

class Dog {
func bark(){
print("Bark")
}
}

după un timp, ne dăm seama că software – ul nostru, ca orice, are nevoie de pisici, așa că creăm o clasă de pisici:

class Cat{
func .meow(){
print("Meow!")
}
}

pentru că natura ne cheamă, adăugăm .caca () la clasa de pisici și câini:

class Dog {
func bark(){
print("Bark")
}
func poop(){
print("Poop")
}
}class cat{
func meow(){
print("Meow")
}
func poop(){
print("Poop")
}
}

în acest exemplu, avem două animale care sunt capabile să facă caca. Din păcate, ambele oferă implementări pentru poop(), deci există o duplicare a codului aici. așa că ne ridicăm .caca () într-o clasă de animale comune.

Animal
.poop()Dog
.bark()Cat
.meow()

acum, că avem o mulțime de animale caca peste tot, avem nevoie de un cleaningrobot:

CleaningRobot
.drive()
.clean()

de asemenea, aveți nevoie de un MurderRobot care poate .conduce () și .ucide () pisicile și câinii care sunt .caca () ing peste tot podelele albe:

MurderRobot
.drive()
.kill()

de atunci .unitate () este acum duplicat între CleaningRobot și MurderRobot vom crea o clasă de Robot să-l pună în.

Robot
.drive()CleaningRobot
.clean()MurderRobot
.kill()

așa arată întreaga structură:

Robot
.drive()CleaningRobot
.clean()MurderRobot
.kill()Animal
.poop()Dog
.bark()Cat
.meow()

„clienții noștri cer un câine criminal. Trebuie să fie în stare .ucide (),.conduce (),.scoarță (), dar nu poate caca ().

și acum suntem terminați. Noi pur și simplu nu se poate potrivi MurderRobotDog frumos în această ierarhie moștenire. Am putea crea un nou obiect părinte, în cazul în care ați pus toate funcționalitățile care este partajat:

GameObject
.bark()Robot
.drive()CleaningRobot
.clean()MurderRobot
.kill()MurderRobotDogAnimal
.poop()DogCat
.meow()

dar asta înseamnă că obiectele dvs. vor avea o mulțime de funcționalități pe care nu le folosesc, așa că veți ajunge cu o problemă de gorilă/banană — solicitați o banană, dar veți ajunge cu o gorilă care ține banana și întreaga junglă cu ea.

cu toate acestea, putem modela acest lucru cu protocoale în Swift.Cum pot protocoalele să ofere o abstractizare mai bună?

un protocol din Swift definește metode sau proprietăți pe care o clasă le poate adopta apoi. Iată un exemplu:

protocol Barker {
func bark()
}
protocol Pooper {
func poop()
}
protocol Driver {
func drive()
}
protocol Cleaner {
func clean()
}
protocol Killer {
func kill()
}

deoarece clasele pot adopta mai multe protocoale. Clasa MurderRobotDog adoptă protocolul Barker, Killer and driver, ceea ce înseamnă că clasa MurderRobotDog oferă implementări pentru bark(), kill(), and clean().

class MurderRobotDog: Barker,Killer, Driver{
func bark() {
print("Bark!")
}
func driver() {
print("Drive!")
}
func killer() {
print("Kill!")
}}

începând cu Swift 2.0, acum putem elimina duplicarea codului oferind o implementare implicită folosind o extensie de protocol:

protocol Barker {
func bark()
}
extension Barker {
func bark() {
print("Bark!")
}
}class Dog: Barker{}
let myDog = Dog()
myDog.bark() // prints "Bark!"

așa că ne-am uitat la un exemplu de arbore de moștenire care s-a stricat și apoi ne-am uitat la cum să-l restructurăm folosind protocolul(interfața).

întrebarea care este probabil în mintea ta acum este-când să o folosești pe fiecare? Ei bine … marea majoritate a dezvoltatorilor sunt de acord că ar trebui să favorizăm interfața în locul moștenirii. O mulțime de oameni sunt de gând să-ți spun că, dacă ceva are o „este o” relație, atunci ar trebui să utilizați moștenire. De exemplu, Mattias „este un” om, astfel pot moșteni omul. Dacă relația este de natură” are”, cum ar fi o mașină „are un” motor, atunci ar trebui să utilizați compoziție.

concluzie

când proiectați un sistem, este important să alegeți principiul de proiectare Potrivit pentru modelul dvs. În multe circumstanțe, este mai bine să utilizați interfața în primul rând. Este mai flexibil, mai puternic și este, de asemenea, foarte ușor de făcut.

Lasă un răspuns

Adresa ta de email nu va fi publicată.