Ví dụ lập trình hướng chức năng

Mặc dù đều là kỹ thuật lập trình sử dụng ngôn ngữ bậc cao, nhưng nếu so sánh lập trình hướng đối tượng và lập trình hướng cấu trúc thì ta có thể dễ dàng phát hiện những điểm không tương đồng giữa 2 phương pháp này. Vậy chúng khác nhau như thế nào? Cùng tìm hiểu qua bài viết dưới đây của Got It.

  • Tìm hiểu thêm: Những mẫu đề thi lập trình hướng đối tượng C++ có thể tham khảo
So sánh lập trình hướng đối tượng và lập trình hướng cấu trúc

1. Đặc điểm của lập trình hướng đối tượng và lập trình hướng cấu trúc

1.1. Lập trình hướng đối tượng

Lập trình hướng đối tượng [OOP] là kỹ thuật lập trình dựa trên “công nghệ đối tượng”, tạo ra các đối tượng trong code trừu tượng hóa các đối tượng thực tế trong thế giới thực. Đối tượng trong OOP có thuộc tính và phương thức. Chúng có thể tương tác qua lại lẫn nhau.

Lập trình hướng đối tượng

OOP có 4 tính chất:

  • Encapsulation – tính đóng gói: các phương thức và dữ liệu có mối quan hệ với nhau được lưu vào một lớp để thuận tiện cho việc quản lý, sử dụng. Chỉ có phương thức nội tại của chính đối tượng mới có thể thay đổi trạng thái nội tại của nó.
  • Abstraction – tính trừu tượng: chỉ tập trung vào những thuộc tính và phương thức cần thiết cho việc giải quyết vấn đề trong lập trình và bỏ qua các thông tin không quan trọng.
  • Inheritance – tính kế thừa: các đối tượng “con” có thể thừa hưởng các đặc tính có sẵn từ đối tượng “cha” mà không cần định nghĩa lại [tùy theo ngôn ngữ lập trình].
  • Polymorphism – tính đa hình: các đối tượng không cùng một lớp, khi tiếp nhận cùng một thông điệp thì sẽ phản hồi theo những cách khác nhau.

1.2. Lập trình hướng cấu trúc

Lập trình hướng cấu trúc [POP] là kỹ thuật lập trình chia nhỏ một chương trình lớn thành các chương trình con [còn được gọi là các hàm]. Mỗi hàm sẽ đảm nhiệm một chức năng khác nhau trong hệ thống. Quá trình phân nhỏ sẽ được thực hiện cho đến khi ra được các hàm đơn giản nhất. Mục đích của việc này là để đơn giản hóa cấu trúc của chương trình, thuận tiện cho việc kiểm tra, sửa đổi và thực thi một cách hiệu quả.

Lập trình hướng cấu trúc

POP có đặc điểm:

  • Chỉ tập trung vào việc phát triển các hàm, ít chú trọng đến dữ liệu
  • Dữ liệu của hệ thống di chuyển từ hàm này qua hàm khác, được dùng chung giữa các hàm.
  • Tuân theo hình thức tiếp cận top-down khi thiết kế chương trình
  • Dùng con trỏ hoặc biến toàn cục để liên kết các hàm với nhau

2. So sánh lập trình hướng đối tượng và lập trình hướng cấu trúc

Có rất nhiều điểm khác biệt giữa lập trình hướng đối tượng và lập trình hướng cấu trúc mà bạn nên quan tâm như:

Trọng tâm

OOP chú ý vào dữ liệu hơn là thuật toán. POP chú ý đến việc xây dựng các hàm và thuật toán hơn là dữ liệu.

Sự phân chia

OOP chia nhỏ chương trình thành các đối tượng. POP chia nhỏ chương trình thành các hàm con.

Chế độ truy cập

Các từ khóa phạm vi truy cập trong OOP được chia thành Public, Private, Protected và Default. POP không có thành phần này.

Hướng tiếp cận khi thiết kế chương trình

OOP tiếp cận từ dưới lên. POP tiếp cận từ trên xuống.

Quá trình thực thi

OOP cho phép các chức năng chạy cùng một lúc. POP cho phép các hàm và chức năng chạy lần lượt.

Truy cập dữ liệu

OOP hạn chế truy cập dữ liệu giữa các đối tượng. POP cho phép dữ liệu tự do di chuyển trong hệ thống và các hàm có thể chia sẻ dữ liệu cho nhau.

Bảo mật

OOP ẩn dữ liệu trong chế độ Public, Protected và Private nên có bảo mật cao. POP không có chế độ ẩn dữ liệu, độ an toàn thấp.

Thêm mới dữ liệu

Hoạt động này có thể được thực hiện dễ dàng với các đối tượng trong OOP, còn POP thì khó hơn.

Nạp chồng/Đa hình

OOP hỗ trợ nạp chồng các hàm, hàm tạo và toán tử còn POP thì không.

Ứng dụng

OOP có thể áp dụng trong xây dựng các chương trình có độ phức tạp cao. POP chỉ nên được dùng với chương trình đơn giản.

Sự ra đời của phương pháp OOP đã khắc phục được nhược điểm của kỹ thuật POP truyền thống, giúp ích cho lập trình viên trong quá trình xây dựng các chương trình. Nếu bạn muốn tìm hiểu thông tin về so sánh lập trình hướng đối tượng và lập trình hướng cấu trúc thì đây chính là bài viết dành cho bạn.

Tìm hiểu thêm:

  • 5 ngôn ngữ lập trình hướng đối tượng phổ biến nhất
  • 7 câu hỏi thường gặp trong phỏng vấn lập trình hướng đối tượng

Hướng đối tượng luôn là một cái gì đó khiến mình và các bạn sinh viên trong trường rất là đau não vì không được trang bị kỹ càng về mặt kiến thức lẫn tính lười biếng và thụ động khi học môn này. Hôm nay, mình sẽ tổng hợp lại về khái niệm này với mong muốn lưu trữ cho bản thân một góc nhìn về OOP cũng như chia sẻ kiến thức tổng quát cho các bạn để các bạn có thể tự trả lời những câu hỏi sau :

  • Hướng đối tượng là gì ?
  • Tại sao sinh ra nó ?
  • Ý nghĩa giữa cuộc sống và lập trình [hướng đối tượng].

Hướng đối tượng đúng như tên của nó là hướng vào một đối tượng, nghĩa là nó có động cơ được xác định từ trước. Lập trình hướng đối tượng là kỹ thuật lập trình nhằm vào sự tương tác giữa các đối tượng.

Mỗi đối tượng [object] có những thuộc tính [property], những phương thức [method] xác định các chức năng của đối tượng. Bên cạnh đó, đối tượng cũng có khả năng phát sinh các sự kiện [event] khi thay đổi thông tin, thực hiện một chức năng hay khi đối tượng khác tác động vào. Tất cả những thuộc tính, phương thức và sự kiện tạo nên cấu trúc của đối tượng. Một ngôn ngữ được gọi là lập trình có tính hướng đối tượng phải đáp ứng được các tuyên ngôn sau [ mình tự gọi là tuyên ngôn hay khái niệm ] :

– Abstraction : tính trừu tượng.

– Encapsulation : tính đóng gói.

– Inheritance : tính kế thừa.

– Polymorphism : tính đa hình.

Mỗi tuyên ngôn đều có vai trò quan trọng trong lập trình hướng đối tượng.

Bạn thường lẫn lộn giữa lớp [Class] và đối tượng [Object]. Cần phân biệt lớp là một khái niệm trừu tượng, còn đối tượng là một thể hiện cụ thể của lớp. Kiểu như 1 cái là Primary và 1 cái là Logical [ Ảo và hiện thực – vật lý ].

[notification type=\”alert-info\” close=\”true\” ]Ví dụ : bản thiết kế nhà là lớp, ngôi nhà được xây dựng dựa trên bản thiết kế là đối tượng. [/notification]

Sự trừu tượng có thể được hiểu đơn giản như sau:

Giả sử, kiến trúc để xây dựng 1 chiếc xe sẽ bao gồm: Bánh xe, yên xe, thắng.

Như vậy, những mô hình xe máy, xe đạp, xe hơi cũng được gọi là xe khi chúng thỏa mãn những yếu tố mà kiến trúc một chiếc xe quy định.

Diễn giải lại điều ở trên bằng hình ảnh để thấy rõ điều đó:

Qua biểu đồ này chúng ta thấy rằng, khi chiếc xe đạp, xe máy, xe hơi kế thừa mô hình xe. Nó sẽ phải định nghĩa 3 phương thức trừu tượng là banhxe[], yenxe[],thangxe[]. Dù rằng ở mỗi thể loại xe đều có những đặc thù riêng biệt.

Như vậy có thể hiểu, mô hình trừu tượng trong thực tế được sử dụng để quản lý mô hình gốc. Nó định ra một quy định cơ bản, và yêu cầu bất kể một lớp nào, hoặc phương thức nào khi muốn làm việc với nó, thì buộc phải định nghĩa theo các quy tắc mà nó đã đặt ra. Nhằm đảm bảo tính nhất quán và dễ kiểm soát mã nguồn hơn đối với các dự án có quy mô lớn và phức tạp.

Tuy nhiên, vì lớp trừu tượng [abstract] vẫn được xem là một lớp. Thế nên, ngoài chức năng quy định lớp trừu tượng ra, thì nó vẫn có thể khởi tạo các thuộc tính [properties] hoặc phương thức[ method ] khác để phục vụ cho việc sử dụng của những phương thức kế thừa nó.

Một ví dụ về việc sử dụng mô hình lớp trừu tượng:

Từ những đối tượng giống nhau, bạn có thể trừu tượng hóa thành một lớp.

Tính trừu tượng cho phép bạn loại bỏ tính chất phức tạp của đối tượng bằng cách chỉ đưa ra các thuộc tính và phương thức cần thiết của đối tượng trong lập trình.

Mỗi lớp được xây dựng để thực hiện một nhóm chức năng đặc trưng riêng của lớp, trong trường hợp một đối tượng thuộc lớp cần thực hiện một chức năng không nằm trong khả năng vì chức năng đó thuộc về một đối tượng thuộc lớp khác, thì nó sẽ yêu cầu đối tượng đó đảm nhận thực hiện công việc.

Một điểm quan trọng trong cách giao tiếp giữa các đối tượng là một đối tượng sẽ không được truy xuất trực tiếp vào thành phần dữ liệu của đối tượng khác cũng như không đưa thành phần dữ liệu của mình cho đối tượng khác một cách trực tiếp. Tất cả mọi thao tác truy xuất vào thành phần dữ liệu từ đối tượng này qua đối tượng khác phải được thực hiện bởi các phương thức [method] của chính đối tượng chứa dữ liệu. Đây cũng chính là một tính chất quan trọng trong lập trình hướng đối tượng gọi là tính đóng gói [encapsulation] dữ liệu.

Tính đóng gói cho phép dấu thông tin của đối tượng bằng cách kết hợp thông tin và các phương thức liên quan đến thông tin trong đối tượng.

[notification type=\”alert-info\” close=\”true\” ]

Ví dụ :

Xe hơi có các chức năng [phương thức phô diễn bên ngoài] như Ngừng, Chạy tới, Chạy lùi. Đây là những gì cần thiết cho Tài xế tương tác với Xe hơi. Xe hơi có thể có một đối tượng Động cơ nhưng Tài xế không cần phải quan tâm. Tất cả những gì cần quan tâm là những chức năng để có thể vận hành xe. Do đó, khi thay một Động cơ khác, Tài xế vẫn sử dụng các chức năng cũ để vận hành Xe hơi , các chức năng [phương thức] đưa ra bên ngoài [Interface] không bị thay đổi.

[/notification]

Tính kế thừa là khả năng cho phép ta xây dựng một lớp mới dựa trên các định nghĩa của một lớp đã có. Lớp đã có gọi là lớp Cha, lớp mới phát sinh gọi là lớp Con và đương nhiên kế thừa tất cả các thành phần của lớp Cha, có thể mở rộng công năng các thành phần kế thừa cũng như bổ sung thêm các thành phần mới.

Bạn phân biệt hai loại quan hệ :

Là – một [ is – any ]

Biểu thị tính kế thừa. Trong quan hệ \”là – một\”, một đối tượng của lớp Con được xem như là một đối tượng của lớp Cha.
Lớp kế thừa

[notification type=\”alert-info\” close=\”false\” ]

Ví dụ :

Từ lớp Xe bạn tạo nên lớp Xe hơi mở rộng, lớp này mặc nhiên kế thừa tất cả các thành phần của lớp xe. Bạn có thể nói một xe hơi là một chiếc xe.

[/notification] Có – một

Quan hệ này mang ý nghĩa gồm có. Trong quan hệ \”có – một\”, một đối tượng có thể có một hoặc nhiều thành phần tham chiếu đến các đối tượng khác.

[notification type=\”alert-info\” close=\”false\” ]

Ví dụ :

Trong mô hình xe hơi, bạn muốn diễn tả ý tưởng chiếc xe \”có – một\” tay lái. Bạn không thể phát sinh lớp Xe hơi từ một Tay lái hay ngược lại [một Xe hơi là một Tay lái]. Thay vì vậy, bạn phải có hai lớp độc lập làm việc với nhau trong đó, lớp phía ngoài [lớp Xe hơi] sẽ tạo và đưa ra công năng của lớp phía trong [lớp Tay lái].

[/notification]

Thể hiện thông qua việc gửi các thông điệp [message]. Việc gửi các thông điệp này có thể so sánh như việc gọi các hàm bên trong của một đối tượng. Các phương thức dùng trả lời cho một thông điệp sẽ tùy theo đối tượng mà thông điệp đó được gửi tới sẽ có phản ứng khác nhau. Người lập trình có thể định nghĩa một đặc tính [chẳng hạn thông qua tên của các phương thức] cho một loạt các đối tượng gần nhau nhưng khi thi hành thì dùng cùng một tên gọi mà sự thi hành của mỗi đối tượng sẽ tự động xảy ra tương ứng theo đặc tính của từng đối tượng mà không bị nhầm lẫn.

Thí dụ khi định nghĩa hai đối tượng \”hinh_vuong\” và \”hinh_tron\” thì có một phương thức chung là \”chu_vi\”. Khi gọi phương thức này thì nếu đối tượng là \”hinh_vuong\” nó sẽ tính theo công thức khác với khi đối tượng là \”hinh_tron\”.

Kết nối trễ – Late Binding

Là khả năng cho phép người lập trình gọi trước một phương thức của đối tượng, tuy chưa xác định đối tượng có phương thức muốn gọi hay không. Đến khi thực hiện, chương trình mới xác định được đối tượng và gọi phương thức tương ứng của đối tượng đó. Kết nối trễ giúp chương trình được uyển chuyển hơn, chỉ yêu cầu đối tượng cung cấp đúng phương thức cần thiết là đủ.

[notification type=\”alert-info\” close=\”false\” ]

Ví dụ :

Bạn có lớp Xe với phương thức Chạy và các lớp Xe đạp, Xe hơi, Xe đẩy cùng phát sinh từ lớp Xe. Bạn chưa biết sẽ sử dụng xe gì đề di chuyển vì tùy thuộc tình hình có sẵn xe nào nên gọi trước phương thức Chạy. Khi chương trình thực thi, tùy theo đối tượng của lớp nào được đưa ra mà phương thức Chạy của đối tượng đó được gọi.

[/notification] Nạp chồng – Overloading

Đây là khả năng cho phép một lớp có nhiều thuộc tính, phương thức cùng tên nhưng với các tham số khác nhau về loại cũng như về số lượng. Khi được gọi, dựa vào tham số truyền vào, phương thức tương ứng sẽ được thực hiện.

Ghi chồng – Overriding

Hình thức này áp dụng cho lớp Con đối với lớp Cha. Lớp Con được phép có một phương thức cùng tên, cùng số tham số có kiểu dữ liệu như phương thức của lớp Cha hoặc những lớp trước đó nữa [lớp phát sinh ra lớp Cha …] với cài đặt khác đi. Lúc thực thi, nếu lớp Con không có phương thức riêng, phương thức của lớp Cha sẽ được gọi, ngược lại nếu có, phương thức của lớp Con được gọi.

Lưu ý là trong  javascript gốc, không có tinh overloading bạn nhé. Thực tế là họ phải fake nó đi, làm một bước trung gian vì bản chất javascript là một ngôn ngữ kịch bản kiểu tuyến tính. Nó giống như đời thường mình vậy nên mình rất hứng thú với nó.

Khi bạn đọc đến dòng này rồi thì chắc bạn cũng đã hiểu, ta không thể lập trình một cái gì đó lớn hơn và rộng hơn nếu ta không sử dụng OOP trong dự án của chúng ta. Đúng vậy, Lập trình Hướng đối tượng được sinh ra giúp ta lập trình vững chắc từng bước một và dễ dàng chia sẻ nhiệm vụ cho mỗi người trong một đội nhóm, dễ dàng bảo trì hệ thống. Đem lại sự yên tâm khi build và sự rõ ràng khi tìm lỗi. Nói chung, nếu bạn áp dụng OOP vào dự án của bạn, bạn sẽ ngủ ngon hơn và có thời gian đi chơi với Gấu mà không bị đau đầu.

Liên tưởng từ lập trình trong máy tính ra lập trình trong cuộc sống. Có rất nhiều điểm tương đồng.

Trong cuộc sống hàng ngày, ta có thể làm những điều ta muốn một cách tuyến tính hay một cách có hệ thống. Đó là tùy ở bạn. Khi bạn lên một plan cụ thể, tức là bạn làm cho cuộc sống của bạn có mục tiêu, đối tượng rõ ràng. Cuộc sống của bạn ví như một hệ thống lớn mà nếu bạn design theo cảm tính ngay từ đầu mà không đặt ra những  mục tiếu rõ ràng [ hướng đối tượng] bạn sẽ gặt lại những thứ không rõ ràng. Đến một lúc nào đó, bạn sẽ không kiểm soát được cuộc đời mình nữa và tương lai bạn sẽ nằm lại trong bàn tay người khác.

Chính vậy, hãy áp  dụng hướng đối tượng vào cuộc sống chỉ với những tuyên ngôn căn bản nhất :

– Abstraction : tính trừu tượng.

– Encapsulation : tính đóng gói.

– Inheritance : tính kế thừa.

– Polymorphism : tính đa hình.

Bạn có thể trừu tượng hóa những kết quả của bạn thông qua những mô hình hay làm những việc nhỏ hơn có hệ thống giống như môi trường thật để có thể thử sai hay gọi là test. Trong máy tính họ gọi là Unit Testing.

Bạn có thể vẻ ra một bản kế hoạch chi tiết và biết được mình đang có những gì, và thiếu những gì để từng bước kết nối với những người ta cần để có thể kéo họ và với ta, giúp ta trong dự án của riêng mình hoặc thuê họ. Trong xã hội thật, người ta gọi đó là OutSourcing.

Trên đường đời bạn đi, luôn có những người thầy, trong kế hoạch của bạn luôn có những công việc giống nhau. Việc của bạn là làm thế nào để tối giản các bước giống nhau đó. Bạn có thể học cách quản lý công việc, thời gian từ những người thầy trên đường đời. Kế thừa từ họ, từ những phần căn bản nhất để rồi mở rộng [ extend] ra với nhiều loại hình khác nhau [ polymorphism] dù cùng chung một nguồn [ source ]. Ví dụ, bạn mở quán cafe, bạn cần người quản lý, bạn cần nhiều cộng sự nhưng làm sao bạn biết bạn cần. Đầu tiên nhất, bạn cần người dẫn đường. Bạn kế thừa kinh nghiệm của người này, mở rộng ra và áp dụng vô trường hợp của bạn và thế là bạn đã tạo ra một hệ thống của riêng bạn.

Thuật ngữ OOP rất hay. Trong nghành IT, mình đã được học nhiều thứ và luôn tìm hiểu tận gốc để có thể hiểu được người nghĩ ra thuật ngữ muốn nói gì và áp dụng vào cuộc sống của riêng mình.

Hãy tự thiết kế cuộc đời mình – LifeStyle Design.

Hy vọng, bạn hài lòng với bài viết của mình. Đừng quên nhấn like để chia sẻ bài viết lên tường nhà bạn và để bạn bè của bạn có thể thấy và hiểu được.

Nguồn : qhOnline

Edit và chỉnh sửa :

AnhThien8.

Video liên quan

Chủ Đề