bij het maken van software is het nuttig om een breed scala aan ontwerpprincipes te begrijpen. Begrijpen hoe je een systeem ontwerpt met het meest geschikte principe kan ontelbare uren van ontwikkeling en hoofdpijn besparen.

laten we eerst even praten over overerving. Overerving is wanneer een klasse toestand en/of gedrag erft van een ouderklasse. Laten we zeggen dat we een spel ontwerpen, en ik heb een hond nodig:

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

na een tijdje realiseren we ons dat onze software, zoals alles, katten nodig heeft, dus creëren we een Kattenklasse:

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

omdat de natuur roept, voegen we toe .poep() naar de kat en de hond klasse:

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

In dit voorbeeld hebben we twee dieren die kunnen poepen. Helaas bieden ze beide implementaties voor poop(), dus er is hier wat code duplicatie. dus tillen we op .poep() in een gedeelde Dierenklasse.

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

nu er overal veel dieren poepen, hebben we een schoonmaakrobot nodig:

CleaningRobot
.drive()
.clean()

je hebt ook een Moordrobot nodig die dat kan .rijden () en .dood () De katten en honden die zijn .poop () ing over je witte vloeren:

MurderRobot
.drive()
.kill()

sindsdien .drive () is nu gedupliceerd tussen CleaningRobot en MurderRobot maken we een Robotklasse om het in te zetten.

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

zo ziet de hele structuur eruit:

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

“onze klanten eisen een Moordrobothond. Dat moet het kunnen .doden(), .schijf(), .schors(), maar het kan niet poepen ().

en nu zijn we de lul. We kunnen de Moordrobothond niet netjes in deze erfhiërarchie passen. We kunnen een nieuw bovenliggend object maken, waar je alle functionaliteit plaatst die gedeeld wordt:

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

maar dat betekent dat je objecten een ton aan functionaliteit zullen hebben die ze niet gebruiken, dus je eindigt met een Gorilla / banaan probleem — je vraagt een banaan aan, maar je eindigt met een gorilla die de banaan vasthoudt en de hele jungle ermee.

we kunnen dit echter modelleren met protocollen in Swift.Hoe kunnen protocollen een betere abstractie bieden?

een protocol in Swift definieert methoden of eigenschappen die een klasse dan kan overnemen. Hier is een voorbeeld:

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

omdat klassen meerdere protocollen kunnen aannemen. De MurderRobotDog klasse neemt het Barker, Killer and driverprotocol aan, wat betekent dat de MurderRobotDog klasse implementaties biedt voor bark(), kill(), and clean().

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

vanaf Swift 2.0 kunnen we nu de code duplicatie verwijderen door een standaard implementatie te bieden met behulp van een protocol extensie:

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

we hebben gekeken naar een voorbeeld van een overerving boom die brak, en vervolgens hebben we gekeken naar hoe het te herstructureren met behulp van protocol (interface).

de vraag die je nu waarschijnlijk moet stellen is-wanneer gebruik je ze allemaal? Nou … de overgrote meerderheid van de ontwikkelaars is het erover eens dat we Interface boven erfenis moeten verkiezen. Veel mensen gaan je vertellen dat als iets een “is een” relatie heeft, dan moet je overerving gebruiken. Bijvoorbeeld, Mattias” is een ” man, dus ik kan de mens erven. Als de relatie van een “heeft een” aard is, zoals een auto “heeft een” motor, dan moet u de samenstelling gebruiken.

conclusie

bij het ontwerpen van een systeem is het belangrijk om het juiste ontwerpprincipe voor uw model te kiezen. In veel omstandigheden, het is gewoon beter om de interface te gebruiken in de eerste plaats. Het is flexibeler, krachtiger, en het is ook heel gemakkelijk te doen.

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd.