när du skapar programvara är det användbart att förstå ett brett spektrum av designprinciper. Att förstå hur man utformar ett system med den mest lämpliga principen kan spara otaliga timmar av utveckling och huvudvärk.

Låt oss först prata om arv för lite. Arv är när en klass ärver tillstånd och / eller beteende från en förälderklass. Låt oss säga att vi utformar ett spel, och jag behöver en hund:

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

efter ett tag inser vi att vår programvara, som allt, behöver katter, så vi skapar en Kattklass:

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

eftersom naturen kallar, lägger vi till .bajs () till katten och hunden klass:

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

i det här exemplet har vi två djur som kan bajsa. Tyvärr tillhandahåller de båda implementeringar för poop(), så det finns lite koddubbling här. så vi lyfter .bajs () i en delad djurklass.

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

nu när vi har många djur pooping överallt behöver vi en rengöringsrobot:

CleaningRobot
.drive()
.clean()

du behöver också en MurderRobot som kan .kör () och .döda () katter och hundar som är .poop () ing över dina vita golv:

MurderRobot
.drive()
.kill()

sedan .drive () dupliceras nu mellan CleaningRobot och MurderRobot vi skapar en Robotklass för att sätta in den.

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

så här ser hela strukturen ut:

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

”våra kunder kräver en Mordrobotdog. Det måste kunna .döda(), .bilresa(), .bark (), men det kan inte bajsa ().

och nu är vi skruvade. Vi kan helt enkelt inte passa MurderRobotDog snyggt i denna arvshierarki. Vi kan skapa ett nytt överordnat objekt, där du lägger all funktionalitet som delas:

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

men det betyder att dina objekt kommer att ha massor av funktionalitet som de inte använder, så du hamnar med ett Gorilla/Bananproblem — du begär en banan, men du slutar med en gorilla som håller banan och hela djungeln med den.

vi kan dock modellera detta med protokoll i Swift.Hur kan protokoll ge en bättre abstraktion?

ett protokoll i Swift definierar metoder eller egenskaper som en klass sedan kan anta. Här är ett exempel:

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

eftersom klasser kan anta flera protokoll. MurderRobotDog-klassen antar protokollet Barker, Killer and driver, vilket betyder att MurderRobotDog-klassen tillhandahåller implementeringar för bark(), kill(), and clean().

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

från och med Swift 2.0 kan vi nu ta bort koddubblering genom att tillhandahålla en standardimplementering med hjälp av en protokollförlängning:

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

så vi har tittat på ett exempel på ett arvsträd som bröt ner, och sedan tittade vi på hur man omstrukturerar det med protokoll(gränssnitt).

frågan som du förmodligen tänker på nu är-när ska du använda var och en? Tja … de allra flesta utvecklare är överens om att vi bör gynna gränssnitt över arv. Många människor kommer att berätta att om något har en” är en ” relation, så ska du använda arv. Till exempel är Mattias ”en” man, så jag kan ärva mannen. Om förhållandet är av en” har en ” natur, till exempel en bil ”har en” motor, bör du använda komposition.

slutsats

när du utformar ett system är det viktigt att välja rätt designprincip för din modell. Under många omständigheter är det bara bättre att använda gränssnittet i första hand. Det är mer flexibelt, kraftfullt och det är också väldigt lätt att göra.

Lämna ett svar

Din e-postadress kommer inte publiceras.