podczas tworzenia oprogramowania przydatne jest zrozumienie szerokiego zakresu zasad projektowania. Zrozumienie, jak zaprojektować system z najbardziej odpowiednią zasadą może zaoszczędzić niezliczone godziny rozwoju i bólu głowy.

najpierw porozmawiajmy o dziedziczeniu. Dziedziczenie jest wtedy, gdy klasa dziedziczy stan i/lub zachowanie z klasy nadrzędnej. Powiedzmy, że projektujemy grę i potrzebuję psa.:

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

po chwili zdajemy sobie sprawę, że nasze oprogramowanie, jak wszystko, potrzebuje kotów, dlatego tworzymy klasę kotów:

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

bo natura wzywa, dodajemy .kupa () do klasy Kot i pies:

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

w tym przykładzie mamy dwa zwierzęta, które są w stanie robić kupę. Niestety, oba zapewniają implementacje dla poop(), więc jest tu pewne powielanie kodu. więc podnosimy .poop() do wspólnej klasy zwierząt.

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

teraz, gdy mamy dużo zwierząt robiących kupę wszędzie, potrzebujemy sprzątaczki:

CleaningRobot
.drive()
.clean()

potrzebujesz też mordercę, który może .drive () i .Zabij() koty i psy, które są .poop()ing all over your white floors:

MurderRobot
.drive()
.kill()

od tamtej pory .drive() jest teraz duplikowane pomiędzy CleaningRobot i MurderRobot tworzymy klasę robota, aby ją umieścić.

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

tak wygląda cała konstrukcja:

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

„nasi klienci żądają MurderRobotDog. Musi być w stanie .kill (),.drive (),.kora (), ale nie może kupy ().

a teraz mamy przesrane. Po prostu nie możemy ładnie wpasować Murderrobotdoga do tej hierarchii dziedziczenia. Możemy utworzyć nowy obiekt nadrzędny, w którym umieścisz wszystkie funkcje, które są współdzielone:

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

ale to oznacza, że Twoje obiekty będą miały mnóstwo funkcji, których nie używają, więc kończysz z problemem goryla/Banana — prosisz o banana, ale kończysz z gorylem trzymającym banana i całą dżunglę z nim.

możemy jednak modelować to za pomocą protokołów w języku Swift.W jaki sposób protokoły mogą zapewnić lepszą abstrakcję?

protokół w języku Swift definiuje metody lub właściwości, które klasa może następnie przyjąć. Oto przykład:

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

ponieważ klasy mogą przyjmować wiele protokołów. Klasa MurderRobotDog przyjmuje protokół Barker, Killer and driver, co oznacza, że Klasa MurderRobotDog dostarcza implementacje dla bark(), kill(), and clean().

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

od Swift 2.0 możemy teraz usunąć duplikację kodu, zapewniając domyślną implementację przy użyciu rozszerzenia protokołu:

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

przyjrzeliśmy się przykładowi drzewa dziedziczenia, które się zepsuło, a następnie przyjrzeliśmy się, jak je zrestrukturyzować za pomocą protokołu(interfejsu).

pytanie, które pewnie teraz nasuwa ci się na myśl, to-kiedy używać każdego z nich? Cóż … zdecydowana większość programistów zgadza się, że powinniśmy faworyzować interfejs zamiast dziedziczenia. Wiele osób powie Ci, że jeśli coś ma związek „jest”, powinieneś użyć dziedziczenia. Na przykład, Mattias „jest” człowiekiem, więc mogę odziedziczyć człowieka. Jeśli związek ma charakter” ma”, taki jak samochód ” ma ” silnik, powinieneś użyć kompozycji.

podsumowanie

podczas projektowania systemu ważne jest, aby wybrać odpowiednią zasadę projektowania dla swojego modelu. W wielu okolicznościach lepiej jest po prostu użyć interfejsu. Jest bardziej elastyczny, wydajny i bardzo łatwy do zrobienia.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.