> 웹 프론트엔드 > JS 튜토리얼 > 상속과 구성

상속과 구성

DDD
풀어 주다: 2024-12-27 03:26:09
원래의
314명이 탐색했습니다.

Inheritance vs Composition

먼저 ES5에서 상속을 달성하는 방법의 예를 살펴보겠습니다.

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
    }
}
로그인 후 복사

다음과 같이 계층 구조를 시각화할 수 있습니다.

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

    Dog
        breed
        bark()

    Cat
        declawed
        meow()
로그인 후 복사

나중에 시스템에 또 다른 엔터티인 사용자를 추가하는 임무를 맡게 되었다고 가정해 보겠습니다.

User
    email
    username
    pets
    friends
    adopt()
    befriend()

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

    Dog
        breed
        bark()

    Cat
        declawed
        meow()
로그인 후 복사

지금까지는 모든 것이 잘 작동하고 멋집니다. 그러나 프로젝트 관리자는 이제 User에게 먹고, 자고, 놀 수 있는 기능도 추가하라고 지시합니다. 어떻게 하시겠습니까? OOP에서 이 문제를 해결하는 방법은 다음과 같습니다.

Mammal
    name
    eat()
    sleep()
    play()

    User
        email
        username
        pets
        friends
        adopt()
        befriend()

    Animal
        energy

        Dog
            breed
            bark()

        Cat
            declawed
            meow()
로그인 후 복사

이제 프로그램이 성장함에 따라 고유한 의미를 갖게 될 또 다른 엔터티를 도입해야 했기 때문에 이는 매우 취약해 보입니다. 이 안티패턴은 일반적으로 God Object라고 불립니다. 따라서 OOP의 문제점은 엔터티를 작성할 때 나중에 요구 사항이 변경됨에 따라 변경될 수 있는 의미를 갖는다는 것입니다. 이러한 변화는 클래스 계층 구조를 무너뜨릴 수 있습니다.

재사용성 부족은 기능적 언어가 아닌 객체 지향 언어에서 발생한다고 생각합니다. 객체지향 언어의 문제점은 그들이 가지고 다니는 암시적 환경을 모두 가지고 있다는 것입니다. 바나나를 원했는데 얻은 것은 바나나를 안고 있는 고릴라와 정글 전체였습니다.
-- 조 암스트롱(Erlang 창시자)

무엇이 무엇인지 생각하기보다는, 무엇을 하는지로 옮겨봅시다.

  • 개는 잠자고, 먹고, 놀고, 짖는 동물입니다.
  • 고양이는 잠자고, 먹고, 놀고, 야옹하는 동물입니다.

이러한 메서드를 클래스에 긴밀하게 결합하는 대신 함수로 사용하고 필요할 때마다 함께 구성할 수 있습니다. 엄청난! 그러면 특정 인스턴스에서 어떻게 작업합니까? 글쎄, 우리는 인스턴스를 함수에 직접 전달합니다. 클로저를 사용하면 함수가 전달된 상태(인스턴스)를 기억할 수 있습니다.

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
    }
})
로그인 후 복사

잠자고, 먹고, 놀고, 짖는 개의 예:

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()
로그인 후 복사

이제 사용자는 먹고, 자고, 놀 수 있습니다.

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

    return Object.assign(
        user,
        eater(user),
        sleeper(user),
        player(user)
    )
}
로그인 후 복사

축하합니다. 긴밀하게 결합된 상속 구조에서 해방되었습니다.

위 내용은 상속과 구성의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:dev.to
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿