Programming languages & Architectural Design

Nguyên tắc cơ bản trong thiết kế OOP: Bài mở đầu

Lý do tôi viết loạt bài này là vì sau nhiều năm đi làm, gặp gỡ nhiều developer ở nhiều lứa tuổi và cấp bậc khác nhau, qua thảo luận, rất nhiều người trong số họ không cắt nghĩa được tại sao mình lại kiến trúc chương trình như vậy. Qua loạt bài viết này, tôi hy vọng cung cấp cho các bạn kiến thức cơ bản về architectural design bao gồm: SOLID, GRASP, GOF Design patterns … và một số kinh nghiệm riêng của bản thân.
Đầu tiên có vài lời tôi muốn nói:
– Nếu các bạn không nằm trong số những người còn chưa nắm vững, chúc mừng bạn và mong bạn góp ý để bài viết tốt hơn.
– Tôi sẽ viết bằng tiếng Việt, rõ rồi, vì tôi đã nói là viết cho đa số các bạn mình mà! Tuy nhiên, tôi sẽ không dùng hoàn toàn 100% tiếng Việt, lý do là đôi khi tôi không tìm ra hoặc ko biết được từ nghĩa tương đương. Tuy nhiên tôi sẽ cố viết sao cho thật dễ hiểu và ngắn gọn.
– Có những thứ tôi chia sẻ từ kinh nghiệm thực tế của mình nên có thể bạn sẽ không tìm thấy từ bất cứ trong một nguồn tài liệu nào cả. 

Ok, giờ ta bắt đầu!

Nguyên tắc cơ bản trong lập trình nói chung, và trong OOP nói riêng, chúng ta chỉ cần code sao cho:
– Ngắn gọn và dễ hiểu. Nghĩa là sau khi code xong, người khác có thể nắm bắt ý tưởng của mình càng nhanh càng tốt. Ít nhất là cho chính bản thân, vài tháng sau quay lại đọc vẫn còn hiểu được mình đã làm cái gì.
– Code càng linh hoạt để đối phó với các sự thay đổi càng tốt. Đơn giản là vì requirement thay đổi liên tục lúc thêm cái này lúc bớt cái khác. Kể cả chính bản thân mình cũng thay đổi ý tưởng xoành xoạch.
Thực ra, giải pháp của chương trình là 1 luồng tư tưởng. Khi người khác đọc vào chương trình của mình, nếu họ năm được luồng tư tưởng này, họ sẽ rất dễ hiểu ý tưởng của mình. Có 2 tư tưởng chủ đạo trong thiết kế bao trùm tất cả mọi thứ ý tưởng khác. Đó là: Sự khái quát hóa (Generalization)sự chuyên biệt hóa (Specification). Hai tư tưởng này đối lập nhau nhưng lại hỗ trợ cho nhau.
– Một vấn đề càng khái quát càng dễ nắm bắt.
Ví dụ: Để lập trình giỏi tôi phải học nhiều và hiệu quả => nghe thì đơn giản, nhưng thế nào là nhiều? thế nào là hiệu quả? học cái gì??? Tuy nhiên người nghe sẽ nắm bắt được ngay ý đồ (muốn giỏi lập trình) và phương pháp (học nhiều và hiệu quả)
– Một giải pháp càng chi tiết càng dễ hình dung và cài đặt, do đó bảo trì và kiểm tra cũng sẽ dễ hơn. Cứ coi như tổng thể chương trình là 1 bài toán lớn. Bạn càng tách nhỏ nó bao nhiêu thì các bài toán nhỏ sẽ dễ giải hơn bấy nhiêu.
Như vậy làm sao để 2 khái niệm này tồn tại chung trong cùng một chỗ?
Đầu tiên, ta chia nhỏ vấn đề thành một chuỗi mắt xích nối tiếp nhau của các vấn đề con. Tại sao gọi là chuỗi mắt xích? Vì ngay sau khi kết thúc xử lý vấn đề này, ta có thể thực hiện ngay bước tiếp theo mà ko cần phải có công đoạn trung gian nào cả. Nếu vẫn còn thì có khả năng lớn là việc khái quát hóa của bạn cần xem lại. Lẽ dĩ nhiên là bạn phải dựa trên ngữ cảnh của bài toán lớn để đánh giá liệu giữa hai vấn đề trong mô hình của bạn còn chỗ hổng hay không.
Ví dụ: Quy trình của một website bán hàng online có thể phân ra thành các bước khái quát như sau:

Tiếp theo, đó là chuyên biệt hóa hay từng bước khái quát. Ví dụ theo mô hình trên, việc tiếp nhận khách hàng có thể chỉ là lấy IP người dùng, có thể là sẽ yêu cầu người dùng login. Phân loại khách hàng có thể phân loại dựa trên behavior của khách hàng rút ra từ hệ thống machine learning nào đó hoặc đơn giản chỉ là lấy dữ liệu từ database. Hoặc giao dịch có thể qua các payment gateway hoặc qua banking v.v… Như vậy chuyên biệt hóa gần giống với việc cung cấp các option cho từng bước khái quát bạn đã đặt ra.

Có thể thấy sau khi phân tích, chương trình của bạn đã có nhiều màu sắc hơn, nhiều lựa chọn hơn và vì thế dễ dàng thích ứng với các sự thay đổi hơn. Quan trọng là, nhìn vào mô hình, bạn biết được toàn bộ xử lý của chương trình, luôn biết phải làm gì và đang làm gì.
Sau này bạn sẽ có thể tìm thấy nhiều nguyên tắc về architectural design ở những nguồn khác, nhưng tất cả về cơ bản cũng chỉ là những biến thể của hai nguyên tắc trên.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s