Advertisement
  1. Code
  2. JavaScript

Kế Thừa và Mở Rộng Đối Tượng với JavaScript

by
Read Time:7 minsLanguages:

Vietnamese (Tiếng Việt) translation by Thai An (you can also view the original English article)

Nếu bạn đã quen thuộc với lập trình hướng đối tượng, bạn có thể quen thuộc với việc phân lớp (subclass) và kế thừa. Tuy nhiên, kế thừa đã nhận được điều tiếng không tốt. Tôi tin rằng bởi một số developer xem nó là một giải pháp chung khi bạn cần để chỉnh sửa một chương trình. Vấn đề là phân cấp của class có thể trở nên không thể quản lý.

Có nhiều design pattern khác mà chúng tôi có thể sử dụng để làm cho ứng dụng của chúng tôi dễ hiểu hơn và sẵn sàng thay đổi. Tôi sẽ chỉ cho bạn các ví dụ về cách bạn có thể sử dụng inheritance và decorator và composite pattern để cải thiện thiết kế của chương trình.

Inheritance (Kế thừa)

Ý tưởng phía sau của inheritance là một đối tượng "là một" phiên bản đặc biệt hoá của một đối tượng khác. Có một class cha (cũng được gọi là superclass), class này định nghĩa những thuộc tính cơ bản của đối tượng. Và có một class con (subclass) - class này kế thừa những thuộc tính của class cha.

Một ví dụ về inheritance là con chó (dog) và giống chó poodle. Tất cả loài chó đều có những đặc điểm nhất định như bốn chân và khả năng sủa. Poodle "là một" loại chó. SUV là một loại xe. Hình tròn là một hình dạng. Đây là phân cấp class của chúng ta sẽ trông như thế nào nếu chúng ta thiết kế một chương trình vẽ các hình dạng.

A basic inheritance diagramA basic inheritance diagramA basic inheritance diagram

Lợi ích của việc có một class Shape là chúng ta có thể tái sử dụng thuộc tính và phương thức mà chúng ta đã định nghĩa trong những class khác.

Chú ý phương thức getArea đã được điều chỉnh lại trong mỗi subclass của chúng ta. Chúng ta không phải định nghĩa lại phương thức này, nhưng chúng ta thay thế các triển khai của phương thức. Đó là bởi vì mỗi hình dạng sẽ có cách tính diện tích riêng của nó.

Overide một phương thức từ class cha trong một class con là một ví dụ cho polymorphism (đa hình). Polymorphism là khả năng cho đối tượng có nhiều hình thức. Nó cho phép các subclass có các phương thức với cùng tên như các superclass nhưng có nội dung khác biệt.

Đây là một ví dụ mà code của chúng ta trông sẽ ra sao khi tạo một Shape và subclass Circle.

Một trong số nhược điểm của chọn lựa thiết kế này là nếu bạn quyết định class cha cần thay đổi, thì các subclass (class thứ cấp) cũng cần thay đổi theo, cùng với những đối tượng chúng ta đã tạo ra.

Ví dụ, giả sử sau đó chúng ta quyết định sẽ tốt hơn khi thay thế các tham số x và y của class Shape bằng một đối tượng. Theo đó, chúng ta cần phải thay đổi constructor cho tất cả các class con của chúng ta và các tham số cho mỗi đối tượng mà chúng ta đã khởi tạo ra.

Chúng ta có thể thấy vấn đề rất dễ xuất hiện. Chúng sẽ phải bảo đảm chúng ta có thiết đúng ban đầu để có thể tránh được việc phải thay đổi. Nhưng thực tế không như thế và đó cũng không phải điều chúng ta nên đấu tranh để thực hiện. Một chương trình là một thực thể luôn tiến hoá, và chúng ta những người phát triển sẽ tốt hơn nếu cho phép việc thay đổi dễ dàng. Ít nhất ta không nên có nhiều hơn 1 cấp class con.

Pattern Decorator

Decorator cho phép chúng ta đình kèm thuộc tính cho một đối tượng sau khi chúng được tạo ra. Điều này có nghĩa là bạn có thể thêm chức năng mà không cần phân thêm class hoặc quan tâm đến phần triển khai của đối tượng.

Thay vì nghĩ một hình tròn (circle) là một shape, chúng ta có thể dùng class Shape để vẽ những hình tròn và gom nó với những thuộc tính bổ sung mà chúng ta muốn. Đây là một cách khác để đối tượng vẽ hình tròn bằng decorator:

Chúng ta có thể thêm hoặc sửa đổi các thành viên của class Shape của chúng ta với một decorator và không cần phân thêm class cho nó. Với ví dụ về shape của chúng ta, có lẽ bạn hiểu rằng bạn chỉ muốn tạo ra một đối tượng circle có tất cả thuộc tính bạn cần và thực hiện tương tự cho những loại shape khác. Điếu đó ổn. Nhưng decorator cho phép chúng tôi sử dụng lại code trong class Shape của chúng tôi và sửa đổi nó với chức năng khác với mỗi hình dạng. Kết quả là, chúng ta sẽ có nhiều đối tượng, nhưng nhiều đối tượng sẽ dễ quản lý hơn nhiều lớp con hơn.

Pattern này không bị giới hạn khị tạo các hình vẽ. Bạn có thể dùng nó bất kỳ trường hợp nào mà bạn muốn bổ sung nhiệm vụ cho một đối tượng.

Ví dụ, chúng ta có lẽ có một class đảm nhận việc đăng ký users vào tài khoản của chúng ta. Trước khi lưu thông tin vào database, sẽ tốt hơn khi kiểm tra rằng thông tin có hợp lệ và không chứa các mã lệnh nguy hiểm. Chúng ta có thể thiết kế class với một phương thức để đánh giá thông tin trước. Decorator tương tự được tái sử dụng bất kỳ đâu trong ứng dụng, những nơi cho phép nhập thông tin của user.

Pattern Composite

Các đối tượng có thể kết hợp với các đối tượng khác. View của một ứng dụng có thể được xem như là một component được kết hợp với những view khác. Nếu chúng ta đang làm game, thì thế giới game của chúng ta sẽ tất cả hình ảnh đồ hoạ chúng ta tạo ra như hình tròn, hình vuông. Mỗi lần chúng ta cập nhập, chúng ta sẽ cần vẽ lại từng thành phần. Chúng ta cần một cách để quản lý các thành phần như một nhóm.

Lúc này pattern Composite có thể giúp chúng ta. Chúng ta có thể tạo một class chịu trách nhiệm cho tất cả thành phần. Khi muốn vẽ lại các thành phần, chúng ta gọi phương thức draw của class này, và nó sẽ gọi phương thức draw cho mỗi thành phần cá thể.

Một trang web có thể xem như là một component. Component này có menu, có sidebar và một blog poost (bài viết). Post sẽ có thể là component con gồm có hình ảnh, tiêu đề và một nội dung. Phương thức draw của component chính sẽ gọi draw trên menu, sidebar và post. Component post sẽ lần lượt gọi draw trên hình ảnh, tiêu đề và nội dung của post.

Đây là view của trang web khi chia nhỏ thành các component:

The Composite PatternThe Composite PatternThe Composite Pattern

Pattern này không bị giới hạn khi tạo các view. Ví dụ, nếu chúng ta đang làm một game, có lẽ ta có một component để quản lý các thầnh phần trên màn hình, một component để quản lý âm thanh, và một component để quản lý trạng thái của game.

Những cái đó sẽ nằm bên trong một component mà ta gọi là game engine (bộ máy cơ chế cả trò chơi). Game engine sẽ có một phương thức khởi tạo sẽ gọi phương thức khởi tạo trong từng component thứ cấp của nó. Đó là sức mạnh của việc sử dụng composite pattern. Thay vì xử lý với từng đối tượng, chúng ta có thể xem nó là một đối tượng.

Tổng kết

Kế thừa cho phép chúng ta tái sử dụng code bằng cách định nghĩa một đối tượng dựa trên một đối tượng khác. Pattern decorator cho phép chúng ta bổ sung nhiệm vụ cho một đối tượng mà không cần phải thay đổi code ban đầu hoặc chia cấp nhỏ hơn các class. Pattern composite mô hình hoá các mối quan hệ toàn phần. Những pattern này không có nghĩa khi sử dụng tách biệt.

JavaScript đã trở thành ngôn ngữ làm việc trên web. Nó đòi hỏi quá trình học tập, và cũng có nhiều framework và thư viện đủ làm bạn bận rộn. Nếu bạn đang kiếm tìm những tài nguyên bổ sung để học hoặc sử dụng trong công việc, hãy xem chúng tôi có gì ở trên Envato Market.

Bạn có thể kết hợp chúng với nhau nếu thấy phù hợp, Ví dụ do tôi cung cấp cũng không phải duy nhất để sử dụng những pattern. Chúng chỉ là những hướng dẫn. Hãy thoải mái sáng tạo khi ứng dụng chúng. Không chỉ có một cách để triển khai chúng hoặc chỉ dùng cho một trường hợp.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.