når du opretter programmer, er det nyttigt at forstå en bred vifte af designprincipper. At forstå, hvordan man designer et system med det mest passende princip, kan spare utallige timers udvikling og hovedpine.

lad os først tale lidt om arv. Arv er, når en klasse arver tilstand og/eller adfærd fra en forælderklasse. Lad os sige, at vi designer et spil, og jeg har brug for en hund:

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

efter et stykke tid indser vi, at vores program, ligesom alt, har brug for katte, så vi opretter en Katteklasse:

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

fordi naturen kalder, tilføjer vi .poop () til katten og Hundeklassen:

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

i dette eksempel har vi to dyr, der er i stand til at kæbe. Desværre leverer de begge implementeringer til poop(), så der er noget kodeduplikation her. så vi løfter .poop () i en delt Dyreklasse.

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

nu hvor vi har en masse dyr, der popper overalt, har vi brug for en rengøringrobot:

CleaningRobot
.drive()
.clean()

du har også brug for en Mordrobot, der kan .Kør () og .dræb() de katte og hunde, der er .poop () ing over dine hvide gulve:

MurderRobot
.drive()
.kill()

siden .drive () er nu duplikeret mellem CleaningRobot og MurderRobot vi skaber en Robot klasse til at sætte det i.

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

Sådan ser hele strukturen ud:

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

“vores kunder kræver en Mordrobotdog. Det skal kunne .dræbe(), .kørsel(), .bark (), men det kan ikke bøje ().

og nu er vi på røven. Vi kan simpelthen ikke passe Mordrobotdog pænt ind i dette arvshierarki. Vi kunne oprette et nyt overordnet objekt, hvor du lægger al den funktionalitet, der deles:

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

men det betyder, at dine objekter vil have masser af funktionalitet, som de ikke bruger, så du ender med et Gorilla/Bananproblem — du anmoder om en banan, men du ender med en gorilla, der holder bananen og hele junglen med den.

vi kan dog modellere dette med protokoller hurtigt.Hvordan kan protokoller give en bedre abstraktion?

en protokol i hurtig definerer metoder eller egenskaber, som en klasse derefter kan vedtage. Her er et eksempel:

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

da klasser kan vedtage flere protokoller. Mordrobotdog-klassen vedtager protokollen Barker, Killer and driver, hvilket betyder, at Mordrobotdog-klassen leverer implementeringer til bark(), kill(), and clean().

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

fra hurtig 2.0 kan vi nu fjerne kodeduplikationen ved at levere en standardimplementering ved hjælp af en protokoludvidelse:

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

så vi har set på et eksempel på et arvetræ, der brød sammen, og så kiggede vi på, hvordan man omstrukturerer det ved hjælp af protokol(interface).

det spørgsmål, der sandsynligvis er i tankerne nu, er-Hvornår skal du bruge hver enkelt? Nå … langt de fleste udviklere er enige om, at vi bør favorisere Interface over arv. Mange mennesker vil fortælle dig, at hvis noget har et “er et” forhold, så skal du bruge arv. For eksempel, Mattias “er en” mand, således kan jeg arve mand. Hvis forholdet er af en “har en” karakter, såsom en bil “har en” motor, så skal du bruge sammensætning.

konklusion

når du designer et system, er det vigtigt at vælge det rigtige designprincip til din model. Under mange omstændigheder er det bare bedre at bruge interface i første omgang. Det er mere fleksibelt, kraftfuldt, og det er også meget nemt at gøre.

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.