Heim > Web-Frontend > js-Tutorial > Vererbung vs. Zusammensetzung

Vererbung vs. Zusammensetzung

DDD
Freigeben: 2024-12-27 03:26:09
Original
313 Leute haben es durchsucht

Inheritance vs Composition

Schauen wir uns zunächst ein Beispiel an, wie wir die Vererbung in ES5 erreichen würden

class Animal {
    constructor(name, energy) {
        this.name = name
        this.energy = energy
    }
    eat(amount) {
        console.log(`${this.name} is eating.`)
        this.energy += amount
    }
    sleep(length) {
        console.log(`${this.name} is sleeping.`)
        this.energy += length
    }
    play(length) {
        console.log(`${this.name} is playing.`)
        this.energy -= length
    }
}

class Dog extends Animal {
    constructor(name, energy, breed) {
        super(name, energy)
        this.breed = breed
    }
    bark() {
        console.log('Woof Woof!')
        this.energy -= .1
    }
}

class Cat extends Animal {
    constructor(name, energy, declawed) {
        super(name, energy)
        this.declawed = declawed
    }
    meow() {
        console.log('Meow!')
        this.energy -= .1
    }
}
Nach dem Login kopieren

Wir können die Hierarchie folgendermaßen visualisieren:

Animal
    name
    energy
    eat()
    sleep()
    play()

    Dog
        breed
        bark()

    Cat
        declawed
        meow()
Nach dem Login kopieren

Angenommen, Sie haben später die Aufgabe, eine weitere Entität zum System hinzuzufügen: Benutzer.

User
    email
    username
    pets
    friends
    adopt()
    befriend()

Animal
    name
    energy
    eat()
    sleep()
    play()

    Dog
        breed
        bark()

    Cat
        declawed
        meow()
Nach dem Login kopieren

Bis jetzt funktioniert alles einwandfrei. Ihr Projektmanager weist Sie jedoch jetzt an, dem Benutzer auch die Möglichkeit zum Essen, Schlafen und Spielen hinzuzufügen. Wie würden Sie es machen? So würden wir das in OOP angehen:

Mammal
    name
    eat()
    sleep()
    play()

    User
        email
        username
        pets
        friends
        adopt()
        befriend()

    Animal
        energy

        Dog
            breed
            bark()

        Cat
            declawed
            meow()
Nach dem Login kopieren

Das sieht ziemlich fragil aus, da eine andere Entität eingeführt werden musste, die nun mit dem Wachstum des Programms ihre eigene Bedeutung haben wird. Dieses Anti-Muster wird im Volksmund „Gottesobjekt“ genannt. Das Problem bei OOP besteht also darin, dass Entitäten beim Schreiben eine Bedeutung haben, die später geändert werden kann, wenn sich die Anforderungen ändern. Diese Änderungen können die Klassenhierarchiestruktur zerstören.

Ich denke, dass der Mangel an Wiederverwendbarkeit in objektorientierten Sprachen auftritt, nicht in funktionalen Sprachen. Denn das Problem bei objektorientierten Sprachen ist, dass sie eine ganze implizite Umgebung mit sich herumtragen. Du wolltest eine Banane, aber was du bekamst, war ein Gorilla, der die Banane und den gesamten Dschungel hielt.
– Joe Armstrong (Erfinder von Erlang)

Anstatt darüber nachzudenken, was die Dinge sind, lasst uns zu dem übergehen, was die Dinge tun.

  • Ein Hund ist ein Schläfer, Esser, Spieler und Beller.
  • Eine Katze ist eine Schläferin, Fresserin, Spielerin und Miauerin.

Anstatt diese Methoden eng an eine Klasse zu koppeln, können wir sie als Funktionen haben und sie bei Bedarf zusammenstellen. Großartig! Aber wie gehen wir dann mit einer bestimmten Instanz um? Nun, wir übergeben die Instanz direkt an unsere Funktionen. Durch den Abschluss können sich die Funktionen den Zustand (die Instanz) merken, der übergeben wurde.

const eater = (state) => ({
    eat(amount) {
        console.log(`${state.name} is eating.`)
        state.energy += amount
    }
})
const sleeper = (state) => ({
    sleep(length) {
        console.log(`${state.name} is sleeping.`)
        state.energy += length
    }
})
const player = (state) => ({
    play(length) {
        console.log(`${state.name} is eating.`)
        state.energy -= length
    }
})
const barker = (state) => ({
    bark(length) {
        console.log(`Woof Woof!`)
        state.energy -= .1
    }
})
const meower = (state) => ({
    meow(length) {
        console.log(`Meow!`)
        state.energy -= .1
    }
})
Nach dem Login kopieren

Beispiel für einen Hund, der schläft, frisst, spielt und bellt:

function Dog(name, energy, breed) {
    let dog = {
        name,
        energy,
        breed
    }

    return Object.assign(
        dog,
        eater(dog),
        sleeper(dog),
        player(dog),
        barker(dog)
    )
}

const dog = Dog('Dog', 10, 'Bulldog')
dog.eat(10)
dog.bark()
Nach dem Login kopieren

Jetzt können Benutzer auch essen, schlafen und spielen:

function User(email, username) {
    let user = {
        email,
        username,
        pets: [],
        friends: []
    }

    return Object.assign(
        user,
        eater(user),
        sleeper(user),
        player(user)
    )
}
Nach dem Login kopieren

Herzlichen Glückwunsch, Sie haben sich von eng gekoppelten Vererbungsstrukturen befreit.

Das obige ist der detaillierte Inhalt vonVererbung vs. Zusammensetzung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:dev.to
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage