Các thuật ngữ kinh điển nhất khi thiết kế hệ thống hướng đối tượng

alt text

Tôi vừa đọc xong cuốn sách "The Object-Oriented Thought Process, 3rd Edition, Matt Weisfeld" nên muốn chia sẻ với mọi người. Ở đây tôi chỉ nêu lên những điều tôi thấy tâm đắc nhất. Vì sách khá dài và viết theo lối hàn lâm "vãi" nên tôi đã dành gần 3 tháng để vừa đọc, vừa ngâm cứu và thực hành cho projects đang làm.

Từ Procedural tới Object-Oriented

Khi làm projects với phương pháp lập trình theo hướng thủ tục (Procedural Programming), các ngôn ngữ thường biết như C, Pascal, BASIC, chúng ta gặp khó khăn khi test và debug vì dữ liệu (data) được tổ chức dạng global và có thể được truy cập và thay đổi bởi nhiều phương thức (functions).

Lập trình theo hướng đối tượng giải quyết vấn đề đó bằng cách đặt dữ liệu và phương thức vào một thực thể hoàn chỉnh, gọi là đối tượng (object); trong đó chỉ những phương thức bên trong đối tượng mới được phép truy cập dữ liệu của nó.

Ví dụ sau đây cho chúng ta thấy được 2 cách tiếp cận khác nhau của việc truyền thông tin giữa client và server.

  • Lập trình hướng thủ tục: client gởi một chuỗi JSON lên server. Server cần phải biết được thông tin bên trong đó là gì để xử lý nó.
  • Lập trình hướng đối tượng: server gởi một applet về client. Client không cần biết bên trong applet đó chứa gì, chỉ cần thực thi chức năng của nó là đủ.

Data hiding

Thuật ngữ đầu tiên tôi muốn đề cập đó chính là "data hiding" hay còn gọi là tính bao đóng (encapsulation). Tôi nghĩ đây là khái niệm cơ bản nhất và kinh điển nhất!

Do đó, khi thiết kế hệ thống hướng đối tượng, chúng ta cần phải luôn giữ trong đầu những nguyên tắc sau:

  • Sự thay đổi của implementation không yêu cần phải thay đổi interfaces. Ví dụ, nhà sản xuất điện thoại thay đổi thiết bị nhưng cách gọi điện là không thay đổi.

  • Sử dụng một abstract interface có tính sử dụng lại cao hơn như "đưa tôi đến sân bay" thay vì dùng nhiều concrete interfaces như "bắt đầu", "rẻ trái", "rẻ phải", "dừng lại", vân vân.

  • Người sử dụng biết càng ít về sự hoạt động bên trong của đối tượng càng tốt. Thiết kế và cung cấp cho người sử dụng cái họ cần ở cái nhìn từ vị trí của họ chứ không phải cái nhìn của hệ thống.

Message

Thuật ngữ "message" ở đây thể hiện cách hoạt động của tính đa hình (polymorphism). Nghĩa là khi chúng ta gởi một "message" đến một object thì object đó phải định nghĩa được chức năng của nó thông qua message đó.

Ví dụ, chúng ta có 3 hình Circle, Square và Star. Cả ba hình này đều được xem như là một hình chung chung gọi là Shape, nhưng khi chúng ta gọi một message là "draw" thì mỗi hình sẽ có cách vẽ khác nhau tùy vào đối tượng đó là gì.

Shape shape = ShapeFactory.get(ShapeType.CIRCLE);
shape.draw();

Code Reuse

Bất kì cách lập trình nào cũng đều quan tâm tới thuật ngữ "code reuse" (sử dụng lại mã nguồn) vì không muốn "phát minh lại bánh xe" hay code bị trùng lặp.

Trong lập trình hướng đối tượng, code reuse được thực thi bởi inheritance (thừa kế) và composition. Tuy nhiên chọn lựa giữa 2 cách này cũng cần phải được xem xét

Inheritance

Được thể hiện thông qua quan hệ "is-a", ở đối hai đối tượng phải thực sự có mối quan hệ cha/con. Ví dụ, chó là (is-a) động vật có vú. :smile:

Thuận lợi: code tập trung vào một nơi (super-class) do đó sẽ tiết kiệm được thời gian viết lại code cũng như thời gian viết test.

Bất lợi: một sự thay đổi trên super-class sẽ ảnh hưởng trên tất cả sub-class của nó.

Vì điểm bất lợi đó nên khi thiết kế theo cách inheritance phải xem xét kỹ 2 đối tượng thực sự có mối quan hệ cha/con hay không. Ví dụ, cửa sổ thì không hẳn là con của hình chữ nhật.

Composition

Được thể hiện thông qua quan hệ "has-a", không phải quan hệ cha/con. Ví dụ, chiếc ô tô có (has-a) một động cơ.

Thuận lợi: giải quyết được vấn đề của inheritance

Bất lợi: sử dụng compostion quá nhiều cấp sẽ làm đối tượng trở nên quá phức tạp.

Hai design pattern tên tuổi và được sử dụng nhiều nhất tương ứng với hai cơ chế này là Strategy -> composition và Template Method -> inheritance.

Contract

Khái niệm "contract" ở đây nghĩa là cơ chế để bắt buộc developers phải làm theo một đặc tả của API. Bởi vì, nếu không có contract thì developers sẽ rất dễ "phát minh lại bánh xe" thay vì sử dụng lại code.

Trong Java, một ví dụ về contract được thực thi là bằng cách sử dụng abstract class hoặc interface.

Lời kết

Cuốn sách tôi nêu trên chủ yếu bàn luận về những điều cơ bản nhất trong thiết kế hệ thống hướng đối tượng và bố cục rất khác với những điều tôi trình bày ở đây. Tuy nhiên những thuật ngữ "data hiding", "message", "code reuse" và "contract" không có gì là mới mẻ, chẳng qua là một cách phân loại khác ở cái nhìn của người thiết kế hệ thống, chung quy lại cũng trở về cách khái niệm cơ bản nhất: "encapsulation", "inheritance", "polymorphism" và "composition".

English version
vnnvanhuong 27-11-2016

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Van Huong

1 bài viết.
13 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Bài viết liên quan
Male avatar
27 10
UML Class Diagram Nếu như muốn biểu diễn mối quan hệ giữa các class như : Aggregation, Composition, Inheritance thì mình nghĩ UML Class Diagram th...
vankhangfet viết gần 3 năm trước
27 10
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
1 bài viết.
13 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!