når du lager programvare, er det nyttig å forstå et bredt spekter av designprinsipper. Å forstå hvordan man designer et system med det mest hensiktsmessige prinsippet, kan spare utallige timer med utvikling og hodepine.

La oss først snakke om arv for litt. Arv er når en klasse arver tilstand og / eller atferd fra en overordnet klasse. La oss si at vi designer et spill, og Jeg trenger En Hund:

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

Etter en stund innser vi at vår programvare, som alt, trenger Katter, så vi lager En Kattklasse:

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

fordi naturen kaller, legger vi til.poop() Til Katten og Hunden klassen:

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

I dette eksemplet har vi to dyr som er i stand til å peke. Dessverre gir de begge implementeringer for poop(), så det er noen kodeduplisering her. så vi løfter .poop () inn i en delt Dyreklasse.

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

Nå som vi har mange dyr pooping overalt, trenger vi en cleaningrobot:

CleaningRobot
.drive()
.clean()

Du trenger også En Mordrobot som kan .drive () og .drep() Katter Og Hunder som er .poop () ing over dine hvite gulv:

MurderRobot
.drive()
.kill()

Siden .drive () er nå duplisert mellom CleaningRobot Og MurderRobot vi lager En Robotklasse for å sette den inn.

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

slik ser hele strukturen ut:

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

«våre kunder krever En MurderRobotDog. Det må være i stand til .drepe(), .stasjon(), .bark (), men det kan ikke peke ().

Og nå er vi skrudd. Vi kan rett og slett ikke passe MurderRobotDog pent inn i dette arvehierarkiet. Vi kunne opprette et nytt overordnet objekt, der du legger all funksjonalitet som er delt:

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

men det betyr at objektene dine vil ha massevis av funksjonalitet som de ikke bruker, så du ender med Et Gorilla / Bananproblem — du ber om en banan, men du ender med en gorilla som holder bananen og hele jungelen med den.

vi kan imidlertid modellere dette med Protokoller I Swift.Hvordan kan protokoller gi en bedre abstraksjon?

en protokoll i Swift definerer metoder eller egenskaper som en klasse deretter kan bruke. Her er et eksempel:

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

Siden Klasser kan vedta flere protokoller. MurderRobotDog-klassen vedtar protokollen Barker, Killer and driver, noe Som betyr At MurderRobotDog-klassen gir implementeringer for bark(), kill(), and clean().

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

Fra Swift 2.0 kan vi nå fjerne kodedupliseringen ved å gi en standardimplementering ved hjelp av en protokollutvidelse:

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

Så vi har sett på et eksempel på et arvetre som brøt sammen, og så så vi på hvordan å omstrukturere det ved hjelp av protokoll (grensesnitt).

spørsmålet som sannsynligvis er i tankene dine nå er — når skal du bruke hver enkelt? Vel … det store flertallet av utviklere er enige om at Vi skal favorisere Grensesnitt over arv. Mange mennesker kommer til å fortelle deg at hvis noe har et» er et » forhold, bør du bruke arv. For Eksempel Er Mattias » en » mann, slik at jeg kan arve mannen. Hvis forholdet er av en» har en » natur, for eksempel en bil «har en» motor, bør du bruke komposisjon.

Konklusjon

når du designer et system, er det viktig å velge riktig designprinsipp for modellen din. I mange tilfeller er det bare bedre å bruke grensesnittet i utgangspunktet. Det er mer fleksibelt, kraftig, og det er også veldig enkelt å gjøre.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.