paint-brush
Kế thừa so với Thành phần: Sử dụng Trò chơi nhập vai trong JavaScript làm ví dụtừ tác giả@kliukovkin
13,348 lượt đọc
13,348 lượt đọc

Kế thừa so với Thành phần: Sử dụng Trò chơi nhập vai trong JavaScript làm ví dụ

từ tác giả Georgii Kliukovkin4m2022/12/21
Read on Terminal Reader

dài quá đọc không nổi

Với thành phần, bạn có thể tránh được các vấn đề về thừa kế và javascript là một ngôn ngữ hoàn hảo để làm điều đó.
featured image - Kế thừa so với Thành phần: Sử dụng Trò chơi nhập vai trong JavaScript làm ví dụ
Georgii Kliukovkin HackerNoon profile picture

Vấn đề thừa kế

  • Sao chép mã ở trẻ em
  • Sự phức tạp quá mức trong hệ thống phân cấp thừa kế
  • Thay đổi hành vi của cha mẹ có thể dẫn đến sai lầm ở trẻ em


Trong bài viết này, chúng ta sẽ xem xét những vấn đề này là gì và cách chúng ta có thể giải quyết chúng bằng bố cục.


vấn đề với các ngôn ngữ hướng đối tượng là chúng có tất cả môi trường ẩn mà chúng mang theo bên mình. Bạn muốn có một quả chuối nhưng thứ bạn nhận được là một con khỉ đột đang ôm quả chuối và toàn bộ khu rừng. - Joe Armstrong, người tạo ra Erlang

Kế thừa trò chơi nhập vai

Hãy xem xét quá trình tạo hệ thống phân cấp nhân vật trong game nhập vai. Ban đầu, cần có hai loại nhân vật - Chiến binh và Pháp sư, mỗi loại đều có một lượng máu và tên nhất định. Các thuộc tính này là công khai và có thể được chuyển đến lớp Character cha.

 class Character { constructor(name) { this.name = name; this.health = 100; } }


Một chiến binh có thể tấn công, tiêu tốn sức lực của mình:

 class Warrior extends Character { constructor(name) { super(name); this.stamina = 100; } fight() { console.log(`${this.name} takes a mighty swing!`); this.stamina--; } }


Và một pháp sư có thể sử dụng phép thuật tiêu tốn một lượng mana:

 class Mage extends Character { constructor(name) { super(name); this.mana = 100; } cast() { console.log(`${this.name} casts a fireball!`); this.mana--; } }

Vấn đề lớp Paladin

Bây giờ, hãy giới thiệu một lớp mới, Paladin . Một Paladin có thể vừa chiến đấu vừa sử dụng phép thuật. Làm thế nào chúng ta có thể giải quyết điều này? Dưới đây là một vài giải pháp có chung sự thiếu thanh lịch:


  • Chúng ta có thể biến Paladin trở thành hậu duệ của Nhân vật và thực hiện cả hai phương thức fight()cast() trong đó từ đầu. Trong trường hợp này, nguyên tắc DRY bị vi phạm vì mỗi phương thức sẽ được sao chép khi tạo và sẽ cần đồng bộ hóa liên tục với các phương thức của lớp Mage và Fighter để theo dõi các thay đổi.


  • Các phương thức fight()cast() có thể được triển khai ở cấp lớp Nhân vật để cả ba loại nhân vật đều có chúng. Đây là một giải pháp tốt hơn một chút, nhưng trong trường hợp này, nhà phát triển phải ghi đè phương thức fight() cho pháp sư và phương thức cast () cho chiến binh, thay thế chúng bằng các phương thức trống hoặc khắc phục lỗi.

Thành phần

Những vấn đề này có thể được giải quyết bằng cách tiếp cận chức năng bằng cách sử dụng thành phần. Nó là đủ để bắt đầu không phải từ các loại của chúng, mà từ các chức năng của chúng. Về cơ bản, chúng ta có hai tính năng chính quyết định khả năng của các nhân vật - khả năng chiến đấu và khả năng sử dụng phép thuật.


Các tính năng này có thể được đặt bằng cách sử dụng các hàm gốc mở rộng trạng thái xác định ký tự:

 const canCast = (state) => ({ cast: (spell) => { console.log(`${state.name} casts ${spell}!`); state.mana--; } }) const canFight = (state) => ({ fight: () => { console.log(`${state.name} slashes at the foe!`); state.stamina--; } })


Do đó, một nhân vật được xác định bởi một tập hợp các khả năng và thuộc tính ban đầu này, cả chung (tên và sức khỏe) và riêng (sức chịu đựng và năng lượng):

 const fighter = (name) => { let state = { name, health: 100, stamina: 100 } return Object.assign(state, canFight(state)); } const mage = (name) => { let state = { name, health: 100, mana: 100 } return Object.assign(state, canCast(state)); } const paladin = (name) => { let state = { name, health: 100, mana: 100, stamina: 100 } return Object.assign(state, canCast(state), canFight(state)); }

Phần kết luận

Với thành phần, bạn có thể tránh các sự cố thừa kế bằng cách sử dụng thành phần và javascript là ngôn ngữ hoàn hảo để làm điều đó.