GIẢI THÍCH CÁC KHÁI NIỆM TRONG OOP – TÍNH ĐA HÌNH – phần 2

Trước khi đọc bài này, xin hãy ngẩng đầu lên trời đọc câu sau 3 lần: “Khi tôi học gì thì phải hiểu đến tận gốc rễ!

Trong phần 2, ta sẽ tìm hiểu virtual❗️, là chìa khóa cho sức mạnh của đa hình, chúng ta cũng sẽ phải đọc một chút ngôn ngữ Assembly. Đây là cách học hại não🏴‍☠️, nhưng nó đáng giá từng phút bạn học, và đảm bảo nếu chịu khó bạn sẽ hiểu thêm được rất nhiều, vậy nên hãy cố lên nhé.

Đọc để biết thêm về Ngôn ngữ Assembly: https://daohainam.com/2023/03/07/the-nao-la-ngon-ngu-lap-trinh-bac-thap-bac-cao/

Trước tiên xin giới thiệu với bạn một công cụ cho phép ta dịch các chương trình sang assembly (hợp ngữ), ta sẽ dùng công cụ này để khảo sát những gì trình biên dịch tạo ra từ chương trình animal.

Bạn truy cập Godbolt tại https://godbolt.org/z/KiMvdD.

Trở lại với chương trình animal, với 2 lớp Dog và Fish. Ta sẽ dịch nó sang mã assembly và xem những gì thực sự xảy ra.

Continue reading “GIẢI THÍCH CÁC KHÁI NIỆM TRONG OOP – TÍNH ĐA HÌNH – phần 2”

Ví dụ về SOLID trong OOP

SOLID là tập hợp 5 nguyên tắc thiết kế các lớp trong OOP, tuân thủ các nguyên tắc này sẽ giúp bạn tạo thiết kế dễ thay đổi, mở rộng, dễ kiểm soát lỗi về sau. Đây là các nguyên tắc mà từ anh fresher tới anh lập trình sư, và cho đến ngày code cuối cùng trước khi xuống lỗ bạn vẫn phải tuân theo (chứ không đến khi con cháu thừa kế lại code ngày nào nó cũng lôi ra chửi 😁).

Vấn đề là làm sao để các bạn hiểu đúng và đầy đủ 5 nguyên tắc này. Tôi đã cố gắng suy nghĩ, tâm tư, tìm hiểu… kể cả lúc đi ăn và đi… ngủ, để tìm xem cách nào giúp các bạn hiểu và nhớ các quy tắc này dễ dàng nhất. Và cách tôi chọn là viết ra 5 ví dụ mẫu, đại diện cho việc vi phạm 5 quy tắc trên.

Các bạn có thể truy cập vào các ví dụ trên tại: https://github.com/daohainam/solid-bad-designs

Cách học là:

– Bạn hãy đọc qua code của từng ví dụ, tốt nhất là theo thứ tự các chữ cái đầu tiên S-O-L-I-D.

– Tự mình suy nghĩ xem có vấn đề gì với thiết kế trên. Bạn nên đặt ra các câu hỏi kiểu như: “Nếu sau này ta muốn thêm”, “Nếu sau này ta muốn thay đổi” … thì phải làm sao?

– Từ đó bạn xem thử khi bạn muốn thêm/thay đổi như vậy thì sẽ gặp vấn đề gì.

– Thử thay đổi lại thiết kế các lớp để giúp thiết kế tốt hơn, giúp giải quyết các vấn đề của bạn.

Chủ đề về phân tích thiết kế là một chủ đề rất thú vị các bạn ạ. Trong thực tế bạn sẽ luôn gặp những vấn đề mà lúc đi học có nằm mơ cũng không tưởng tượng ra được 😀. Bạn sẽ học mãi, học mãi, tìm giải pháp, giải quyết vấn đề, một hôm nào đó lại thấy một vấn đề mới trong giải pháp tưởng chừng hoàn hảo đó, rồi lại học, lại suy nghĩ…

Tôi sẽ cập nhật thêm mô tả các vấn đề và giải pháp. Các bạn nhớ truy cập vào repository và tặng cho nó 1 Star nếu thấy hay nhé, xin cảm ơn trước! 😘

LÀM QUEN VỚI PHÂN TÍCH THIẾT KẾ

Một trong những câu hỏi tôi luôn suy nghĩ trong đầu khi bắt đầu bước vào ngành phần mềm là làm thế nào để từ một bài toán thực tế ta có thiết kế ra được các thành phần bên trong một cách đúng đắn: DLL, class, property… Tôi tin rằng các bạn cũng có cùng câu hỏi như vậy, có một kiến thức tốt về thiết kế không chỉ giúp cho công việc hiện tại mà còn mở ra một chân trời mới trong con đường sự nghiệp của bạn.Loạt bài này sẽ giúp bạn có được những kiến thức vững chắc về thiết kế phần mềm, và vì có khá nhiều vấn đề liên quan đến thiết kế nên tôi sẽ viết ra thành nhiều bài theo thứ tự, các bạn chịu khó theo dõi nhé.

Trước khi bắt đầu, ta cần thống nhất với nhau vài điều:

– Kiến thức về OOP là bắt buộc, các phương pháp thiết kế ở đây đều yêu cầu một nền tảng tốt về OOP ❗️.

– Tôi sẽ không viết riêng cho một nền tảng hay ngôn ngữ nào, nhưng sẽ tập trung vào Java và .NET, cùng các ngôn ngữ là Java và C#. Đây là hai trong những nền tảng phổ biến và tốt nhất, đặc biệt cho việc xây dựng các ứng dụng lớn.

– UML: Bạn không cần biết trước về UML, nhưng nếu có kiến thức về nó sẽ rất tốt, đôi khi tôi có thể dùng nó để mô tả.

Continue reading “LÀM QUEN VỚI PHÂN TÍCH THIẾT KẾ”

VIRTUAL ABSTRACT CLASS VÀ INTERFACE

Một trong những câu hỏi thường gặp nhất khi học OOP là: (Virtual) abstract class và Interface khác nhau chỗ nào? Và khi nào sử dụng cái nào?

ℹ️ Câu trả lời đơn giản nhất là: Nếu ngôn ngữ của bạn có hỗ trợ interface thì hãy dùng nó, đừng nghĩ gì về abstract class nữa.Để hiểu hơn về 2 thứ này, ta cần hiểu một chút về trừu tượng trong (abstraction) OOP.

Continue reading “VIRTUAL ABSTRACT CLASS VÀ INTERFACE”

BÀN VỀ FUNCTIONAL PROGRAMMING VÀ OOP PROGRAMMING – bài 2

Vậy là chúng ta đã biết về cả OOP và FP, giờ là câu hỏi quan trọng nhất: Tôi nên đi theo con đường nào?

Thật sự khi viết bài này (cả bài phần 1), tôi không có ý định chỉ ra OOP hay FP tốt hơn, và chọn con đường nào hay hơn. Chính tôi cũng không biết nếu chọn FP thuần túy thì bạn sẽ làm gì ngoài các ứng dụng chuyên về phân tích và xử lý số liệu, mà tôi tin là con số này sẽ rất ít so với phần còn lại.

👉 Thực chất, FP và OOP là hai phương thức tư duy về cách tổ chức các thành phần bên trong ứng dụng. FP cho phép đơn giản hóa việc xử lý các luồng dữ liệu, chia bài toán lớn thành các bài toán con giúp mô hình tổng thể trở nên đơn giản hơn. Nhờ vậy việc viết ra (implement) các đoạn code sử dụng FP trở nên dễ hiểu và ngắn gọn hơn. Ngược lại, OOP phát triển dựa trên các khái niệm từ thế giới thực, và có thể nói OOP khó hiểu và phức tạp hơn FP rất nhiều. Vấn đề là, hầu hết các bài toán ta cần xử lý đều là các bài toán từ thực tế, với các đầu vào, quan hệ, trạng thái cũng từ thực tế, đặc biệt nhìn từ góc độ phân tích, thiết kế và xây dựng kiến trúc hệ thống. Và cũng vì vậy, nếu không có kiến thức về OOP, bạn sẽ khó có thể thiết kế ra các hệ thống phức tạp như trên.

Khi xưa lúc chưa có OOP, người ta vẫn có thể viết ra phần mềm, nhưng thật sự các phần mềm khi đó về quy mô, yêu cầu còn rất đơn giản so với hiện tại. Cũng như các mô hình phát triển ứng dụng kiểu waterfall trước đây vẫn giúp tạo ta các ứng dụng hữu ích, những với các ứng dụng lớn hiện tại, áp dụng mô hình này gần như không khả thi.

Nhìn vào các ngôn ngữ phổ biến nhất hiện tại, ta sẽ thấy không có ngôn ngữ nào là OOP only, hay FP only, mà hầu hết sẽ hỗ trợ cả hai: C#, VB, Java, JS… tất cả đều có OOP và cả FP, những ngôn ngữ vốn thuần túy OOP như C# và Java giờ cũng đều có lambda, JS vốn khi ra đời chỉ là một ngôn ngữ cực kỳ đơn giản, giờ cũng hỗ trợ cả OOP lẫn FP. Nếu nói là chỉ theo OOP hay FP, vậy bạn đang sử dụng ngôn ngữ nào?

👉 Vậy cuối cùng, tôi nên theo con đường nào?Tôi nghĩ đây là một câu hỏi thừa, nếu muốn trở thành một người lập trình chuyên nghiệp, chẳng có lý do gì bạn không thành thạo cả hai. Một người thợ chặt cây nên biết dùng cả cưa và rìu, đừng tự đặt ra câu hỏi tôi nên thành thạo cái nào, vừa mất thời gian vừa tự hạn chế khả năng của mình.FP trong các ngôn ngữ hiện tại giúp bạn viết code rất nhanh và hiệu quả, nếu bây giờ bắt tôi viết C# mà không sử dụng lambda, chắc tôi sẽ thấy chán khi viết các đoạn lệnh tìm kiếm, sắp xếp dài dòng. Còn OOP, với nhiều ưu điểm đã nói đến trong các bài trước, sẽ giúp bạn thiết kế ra các chương trình hiệu quả. Cả FP và OOP đều có những ưu điểm riêng, bạn hãy cố gắng thành thạo cả hai và sử dụng chúng đúng chỗ.

👉 Nên nhớ, OOP là cả một phương pháp thiết kế, nếu đọc qua các design parttern bạn sẽ thấy tất cả đều dựa trên OOP – tôi sẽ vô cùng ngạc nhiên nếu bạn đặt mục tiêu sau này trở thành một software designer, hay một software architecturer, nhưng lại không có ý định tìm hiểu sâu về OOP.

BÀN VỀ FUNCTIONAL PROGRAMMING VÀ OOP PROGRAMMING – bài 1

Cách đây mấy hôm tôi có đưa ra một khảo sát xem mọi người sẽ theo hướng FP hay OOP, vì hay gặp cảnh tranh cãi giữa hai trường phái này. Và thường các cuộc tranh cãi đều không có hồi kết, đơn giản vì ai cũng có lý lẽ của mình, và quan trọng nhất là không có ai có thể đưa ra được những lý do xác đáng để bên kia tin theo.

Trong bài này tôi sẽ mặc nhiên coi các bạn đã hiểu về OOP, và sẽ nói một chút về FP (vì trong blog này chưa có bài nào nói về nó). Nếu như bạn chưa thực sự biết rõ cả OOP lẫn FP thì tất cả những lý lẽ đưa ra sẽ đều là cảm tính, do đó quan điểm đưa ra sẽ dễ trở nên phiến diện và không thuyết phục.

Nhớ tìm đọc lại các bài OOP nếu bạn vẫn chưa nắm rõ nhé ❤️.

ℹ️ Vậy Functional Programming là gì?

Continue reading “BÀN VỀ FUNCTIONAL PROGRAMMING VÀ OOP PROGRAMMING – bài 1”

TÍNH TRỪU TƯỢNG

Tính trừu tượng – mới nghe đã thấy mệt mỏi rồi 🥴.

Như trong những bài viết trước, ta đã thấy trừu tượng là khái niệm mà chúng ta luôn cố gắng hiện thực khi xây dựng phần mềm.

Nói một cách đơn giản, trừu tượng cho phép ta làm việc với các thành phần khác mà không cần quan tâm chúng được xây dựng như thế nào, không cần biết bên trong một lớp người ta viết gì và chúng ta không cần phải quan tâm đằng sau chúng có những thành phần nào để chạy.

Trong OOP, với bài toán quản lý sinh viên, ta tạo ra một lớp cha StudentStore, trong đó có 2 phương thức Find and Save, dùng để tìm và lưu trữ thông tin về các sinh viên.Trong phiên bản đầu tiên, Find và Save sẽ đọc và lưu lại thông tin vào các file trên đĩa. Nhưng đến khi bạn học sang phần Sql Server, bạn muốn lưu trữ vào cơ sở dữ liệu thay cho file, vì tất nhiên làm việc với dữ liệu trên file sẽ cực nhọc và kém hiệu quả hơn nhiều. Lúc đó bạn sẽ làm gì?

Continue reading “TÍNH TRỪU TƯỢNG”

GIẢI THÍCH CÁC KHÁI NIỆM TRONG OOP – TÍNH ĐA HÌNH (Polymorphism)

Đa hình là tính chất quan trọng nhưng khó hiểu nhất của OOP – nắm bắt được tính chất này, bạn sẽ dễ dàng hiểu được tất cả những gì còn lại, kể cả tính trừu tượng sau này. Trong bài này tôi sẽ giải thích nó theo cách đơn giản nhất, sau đó trong phần 2 ta sẽ đào sâu vào, xem những gì thực sự xảy ra ở bên dưới.

👉 Giải thích đơn giản thì đa hình cho phép tự động gọi một phương thức dựa trên các tham số truyền vào (1) hoặc kiểu thực sự của đối tượng bạn đang có (2). (1) Nếu bạn có 2 phương thức:

function Add(x, y : Integer) : Integer;
begin
    Add := x + y
end;
function Add(s, t : String) : String;
begin
    Add := Concat(s, t)
end;
Continue reading “GIẢI THÍCH CÁC KHÁI NIỆM TRONG OOP – TÍNH ĐA HÌNH (Polymorphism)”

GIẢI THÍCH CÁC KHÁI NIỆM TRONG OOP (phần 2)

Thừa kế cho phép ta tạo một lớp mới mở rộng từ một lớp khác, lớp mới được gọi là lớp con, lớp thừa kế hay lớp dẫn xuất (derived class), mình hay gọi là lớp con cho nhanh.

Lớp cha còn gọi là lớp cơ sở.Ưu điểm dễ thấy nhất là ta có thể tạo ra một lớp con mới tận dụng các tính năng có sẵn được cung cấp từ lớp cha, hay còn gọi là khả năng sử dụng lại.

Ấy nhưng đó lại chẳng phải là nguyên nhân người ta cho ra đời tính chất này, bởi nếu bạn đã có sẵn những tính năng đó thì dù có hay không khả năng thừa kế, bạn vẫn có thể tạo ra những lớp mới gọi lại các tính năng đó.Ưu điểm chính của thừa kế là nhờ có nó ta mới có được đa hình (polymorphism), và nhờ đa hình mà ta có trừu tượng (abstract).

❗️Trừu tượng là thứ mà tất cả những nhà thiết kế phần mềm đều muốn sử dụng càng nhiều càng tốt: các driver cho phép phần mềm giao tiếp với các thiết bị khác nhau khi dùng chung một phương thức, các file system driver giúp tương tác với các file trên đĩa mà không cần quan tâm chúng được định dạng với NTFS, HTFS, FAT hay Ext3, ngôn ngữ SQL cho phép làm việc với các cơ sở dữ liệu mà không cần biết chúng được lưu trữ thế nào, HTTP cho phép xem các trang web mà không cần quan tâm máy chủ của nó hoạt động ra sao… Có vô số các ví dụ như vậy. Vì thực sự thừa kế rất dễ hiểu nên tôi sẽ chỉ giải thích một số khái niệm liên quan:

Continue reading “GIẢI THÍCH CÁC KHÁI NIỆM TRONG OOP (phần 2)”

GIẢI THÍCH CÁC KHÁI NIỆM TRONG OOP (phần 1)

Tiếp theo các bài viết về tầm quan trọng của OOP trong lập trình, tôi sẽ tiếp tục giải thích kỹ hơn về các khái niệm có trong OOP. Tôi sẽ chỉ nói về ý tưởng, và cách thiết kế một cách hợp lý, tức là vì sao có nó và nên sử dụng nó như thế nào. Việc giới thiệu và cách viết trong từng ngôn ngữ cụ thể bạn có thể đọc được từ rất nhiều tài liệu khác có trong trường học và Internet.

OOP sẽ rất dễ hiểu nếu bạn nhìn từ góc độ cuộc sống, bạn đọc một khái niệm, tìm một ví dụ trong đời thực mô tả khái niệm đó, khi đã tìm được ví dụ bạn sẽ dễ dàng hiểu được nó.

Nhớ là các khái niệm trong OOP có sự liên hệ lẫn nhau, nên sẽ rất khó nếu bạn cố gắng học và hiểu toàn bộ từng-cái-một, cách tốt nhất là đọc toàn bộ, phần nào chưa hiểu hết cứ bỏ qua, rồi lại đọc lại toàn bộ một lần nữa, lần này bạn chỉ đọc những chỗ đã bỏ qua ở lần trước. Cứ lặp đi lặp lại như vậy, lúc nào đó bạn sẽ nghiệm ra và hiểu tất cả.

Continue reading “GIẢI THÍCH CÁC KHÁI NIỆM TRONG OOP (phần 1)”