Đôi lời về lập trình hướng đối tượng (OOP) ? Từ một người trẻ đang trên con đường làm game
Thật ra OOP không khó, cũng không dễ. Không khó là vì, bản chất nó sinh ra là vì con người ta vốn có sẵn cái lý tính, lý tính giúp chúng ta phân biệt các “hình thức” rồi tự gán ý niệm vào “hình thức” đó, gọi nhanh có thể gần giống với công việc phân loại. Đúng là con người rất thích phân loại, thế nên mới sinh ra đủ các thể loại con, giống, bộ, lớp, nhánh, thể loại,… Nhưng không dễ, là vì không phải ai cũng biết cách phân loại đúng. Để đạt được đến tầm kiến thức có thể đưa ra được ý niệm chính xác về 1 sự vật sự việc, thì có thể mất rất nhiều công sức suy nghĩ và tìm tòi. Nếu không là một người yêu thích triết học, thì bạn đôi khi khó làm được.
Nhưng ban đầu thì người ta lại lập trình theo hướng thủ tục. Hãy coi như não con người có 1 phần chuyên dùng để hiểu vấn đề đi, nếu thế thì hướng thủ tục là gần với cái não này nhất, ý là não sẽ dễ hiểu lập trình hướng thủ tục nhất. Vì nó sát nghĩa với bài toán đặt ra, cần tính chu vi, có ngay 1 đoạn code tính chu vi, cần tính diện tích, có ngay 1 đoạn code tính diện tích. Vì thế nên ban đầu khi đi học, mình được học lập trình hướng thủ tục, và nó vẫn ăn sâu vào máu đến tận bây giờ.
Đến khi làm việc với tư tưởng OOP, mình thấy nó hay ở điểm thế này: Mục tiêu chính của OOP chính là “tóm gọn” các thủ tục lại, người ta hay gọi là “đóng gói” đấy. Có nghĩa là, 1 công việc thì có rất nhiều việc cần làm, để làm ra 1 game thì bạn phải chia studio của bạn ra làm nhiều vị trí, ví dụ như 1 bên thì vẽ chi tiết, 1 bên thì tính toán vật lý và các véc tơ, 1 bên thì sáng tạo kịch bản, rồi còn có hẳn 1 bên chuyên làm giám sát tất cả các bên rồi đưa ra đánh giá,… Đó, chung quy lại, vẫn là thực hiện các thủ tục, nhưng chỉ là bạn chia nó ra cho từng người và chuyên môn hóa nó thôi. OOP cũng vậy, bạn tạo ra một đối tượng, thì mục đích duy nhất của bạn là để đối tượng đấy của bạn giải quyết 1 công việc nào đó nào cho bạn. Nói như vừa rồi thì ngược, đáng lẽ phải là: tôi cần giải quyết công việc này, vậy nên tôi tạo ra 1 đối tượng và để nó giải quyết giúp tôi. Vấn đề khó khăn ở đây là làm sao để bạn biết được công việc cần phải giao cho đối tượng là gì, nó đã đúng để có thể chuyên môn hóa chưa.
Đối tượng, là một nhân vật có thể giải quyết một tập hữu hạn các công việc đã biết trước tính chất, và mỗi công việc đó, lại là 1 thủ tục.
Trong cái này thì có cái kia, vậy đó. Như là âm dương vậy.
p/s: Bài viết rất ngẫu hứng, các bạn cứ cmt cơ mà đừng quan trọng tính đúng sai. Mục đích duy nhất mình post lên là để tranh luận.
mình thấy bây giờ đa phần các bạn sinh viên chỉ biết về lập trình hướng đối tượng, vì hầu như các trường chú trọng dạy cái này thì phải . riêng mình thì cảm thấy hứng thú với functional hơn. cảm giác nó giống những thứ sơ khai của lập trình. những nguyên lí của nó cũng khá hay. đôi khi cảm giác oop nó gom những thứ không đồng nhất lại vào một thấy sao sao đó. mình thích làm với javasript vì có thể thấy dc cả functional programing và oop trong đó :)))
Xin chào.
Mình không phải dân chuyên lập trình, mình học cơ điện tử năm 3 và mình chỉ tự học lập trình bằng C# để làm Unity, vì Unity yêu cầu C# và OOP. Hiện tại thì mình vừa học Unity vừa học cuốn “Giáo trình ngôn ngữ C#”
Hồi cấp 3 thì mình có học Pascal và các giải thuật cơ bản để đi thi thôi, gọi là biết cách đọc hiểu thuật toán.
Bạn có thể giải thích giúp mình Functional không ?! Nó là lập trình theo tư tưởng như thế nào ?!
Như đã nói ở trên, sau 1 thời gian tìm hiểu và làm việc với C#, với Unity, và với xuất phát điểm như đã kể trên thì mình ngẫm ra được như vậy. Mình thấy OOP nó hay ở chỗ là nó phù hợp cho những công việc như tạo công cụ, hay làm game như mình. Vì nó giúp tạo ra 1 “nhân vật”, và dạy “nhân vật” đó làm công việc gì đó. Sau này, khi muốn làm công việc đó thì mình chỉ cần gọi “nhân vật” đó ra thôi.
có link này khá hữu ích vì giải thích khá dài dòng. nói chung thì mỗ loại đều có điểm mạnh riêng. http://vnoi.info/wiki/translate/functional-programming-part-1
Imperative programming và functional programming là 2 kĩ thuật lập trình khác nhau. Ngoài ra còn có declarative programming, reactive programming.
OOP - lập trình hướng đối tượng, là 1 nhánh con của imperative programming - lập trình hướng thủ tục. Vì đa số project chủ yếu dùng OOP nên dễ hiểu nhầm OOP là 1 cách lập trình riêng.
Functional không khó các khái niệm nó cũng dễ mà khi Functional Thinking thật sự rất khó cho những ngôn ngữ thuần nó. Mình trước đây cũng chỉ biết Imperative . Về sau học Swift mới biết rõ hơn . Thời này Functional có vẽ lên lắm máy dòng CPU bây h toàn multi core .
đúng rồi bạn, h càng ngày càng thấy nhắc đến functional programming nhiều hơn
Hay thật, bởi vì mình không là dân chuyên sâu về lập trình, mình lập trình chỉ là phụ thôi vì mình làm game là chính (làm game thì mình cũng làm về phần producer hơn là phần developer).
Hôm nay các bạn nói mình mới vỡ ra nhiều điều. Mình cũng đang đọc về Functinal Programming đây.
Bản thân mình là một người ham mê triết học, thế nên những tư tưởng mới hay những quan điểm mới mình rất thích.
Các bạn có thể chỉ rõ hơn cho mình về các quan điểm programming không ?! Xin cảm ơn rất nhiều.
Thường mỗi cách lập trình (functional, OOP) sẽ có 1 tập các ngôn ngữ lập trình (programming languages) hiện thực. Ngược lại, 1 ngôn ngữ lập trình cũng sẽ hiện thực nhiều phong cách lập trình khác nhau, tuy nhiên có 1 cách lập trình là nổi trội hơn cả. Vì vậy, để học cách lập trình bạn chỉ cần học ngôn ngữ lập trình tiêu biểu của nó. Dưới đây là một số ví dụ, theo ý kiến cá nhân:
Imperative: C
OOP: Java, C#, Python
Functional : Haskell, Erlang, Elixir
Declarative: Prolog, SQL
Reactive: Haskell, ReactiveX library
@khanhsieunhan b hoc cơ điên tư mà làm game a , không đinh theo ngành học sau này sao ? tương lai b đih làm j ?
Mình học cơ điện tử là hồi cấp 3 muốn học 1 ngành kỹ thuật cơ mà không phải cơ khí hay CNTT hay điện thôi Thấy cơ điện tử hay hay nên học, chứ sở thích, cũng là khả năng và sở trường của mình là lập trình và sáng tạo kịch bản (hồi cáp 3 còn viết tiểu thuyết rồi cơ )
Hiện tại thì mình đang cố học cho lấy cái bằng cho đỡ tốn tiền tốn công học, còn tương lai thì mình sẽ chuyên tâm làm game thôi. Mình đang tự học Unity, vì thấy nó gọn nhẹ, phù hợp sử dụng cho các dự án nhỏ như mình.
Mong ước là có studio riêng, có nhà đầu tư, dùng hẳn tới Unreal Engine làm game AAA
@khanhsieunhan nhưg b chuyên ngah cơ điên tư , sau xin vào các cty CNTT găp khó khăn đây , vi ho ưu tuyên ngươi hc đug chuyên ngah hơn
ừm hiện tại mình đang hướng làm game độc lập hơn là theo vào 1 công ty nào đấy, vì theo vào công ty thì mình chỉ có làm theo ý tưởng của họ thôi, và tiền kiếm ra cũng không nhiều, ngoài ra thì mình không chuyên về lập trình mà chỉ học đủ để làm game thôi. ý tưởng thì mình có rồi, mình hiện tại cũng không định làm game lớn mà chỉ tập trung vào những game nhỏ có gameplay hay trước. mục tiêu của mình cũng là kiếm tiền thôi, không còn gì khác. thế nên mình nghĩ là mình sẽ làm nhà phát triển độc lập hơn chứ không học rồi đi làm theo 1 công ty nào đấy.
nhưng về sau khi phát điển được đến có 1 studio thì mình cũng mong studio của mình được công ty nào đó bảo trợ, như vậy sẽ chắc chắn hơn về mặt kinh tế.
sức mạnh của OOP chính là phân tích vấn đề từ dưới lên và 1 chương trình viết theo OOP thì nó rất dễ để mở rộng cũng như bảo trì , và mỗi phương pháp lập trình đều có điểm mạnh và yếu riêng của nó . OOP nó dùng kỹ thuật trừu tượng hóa dữ liệu để mô tả các đối tượng từ thế giới thực để đưa vào lập trình vì vậy có thể nói nó là 1 phương pháp LT sát với thực tế nhất . Mà bạn hình như cũng chưa học sâu về OOP thì phải vì OOP nó giải quyết bài toán theo hướng từ dưới lên nên khác với lập trình thủ tục từ trên xuống .Với lập trình thủ tục có thể bạn sẽ giải quyết vấn đề bằng cách chia nhỏ nó ra sau đó sẽ giải quyết từng vấn đề nhỏ , nên sau này nếu có thay đổi trong bài toán thì việc sửa hay mở rộng rất khó khăn , ngược lại OOP phân tích vấn đề từ những chi tiết nhỏ nhất sau đó sẽ dần mở rộng nó ra nên việc thay đổi và mở rộng lại rất dễ dàng . Bản chất của OOP không phải là đi giải quyết từng vấn đề như thủ tuc bạn nên hiểu đươc cái này…
Ngoài ra còn có LT logic , LT hàm mỗi loại LT đều có mục đích riêng của nó nên hiểu rõ bản chất của nó để áp dụng đúng nơi đúng lúc…
Bản thân mình thì mình thích Hướng đối tượng OOP hơn …Vì dễ trình bày,dễ quản lí,dễ sửa …
làm game đọc lập chắc chịu nhiều áp lực về tài chính lắm anh nhỉ
cảm ơn bạn, đọc cmt của bạn ra mình hiểu ra rất nhiều. đúng là mình vẫn đang tự ngẫm nghĩ về điểm khác biệt mấu chốt của OOP và hướng thủ tục thuần túy. Mình có thể đúc lại như sau:
Vd có một bài toán là xử lý một dãy số, đầu tiên là các phần tử lên với 2, sau đó là cộng với 3.
Đó là suy nghĩ của mình trong 2 tiết học ở trường từ khi đọc được cmt của bạn, giờ về nhà mới kịp reply. Mong bạn cho ý kiến.
Mình cũng đang thử so sánh giữa OOP và lập trình hàm, thấy 2 cái này nó khá gần nhau. Vì cùng xây dựng các hàm sẵn làm công cụ cho mình.
Đúng là nếu mình tự làm thì rất áp lực về tài chính do không có nguồn thu. Lập trình viên Instagram cũng đi làm thêm ban ngày còn tối về tự học lập trình đó, như thế mới có tiền trang trải.
Cơ mà mình vẫn đang đi học nên may mắn là không bị lo lắng về khoản này.
Hướng thủ tục hay OOP đều có thể phân tích theo top-down hoặc bottom-up, không phải là OOP chỉ có thể làm bottom-up. Bạn hoàn toàn có thể đi từ business requirement -> use-case diagram -> class + sequence diagrams -> detail design -> implementation để viết ra 1 app thuần OOP.
Trong lập trình hướng thủ tục nói chung, hay OOP nói riêng (OOP là nhánh con của thủ tục) có khái niệm abstraction và module. App bao gồm nhiều module, các module có các chức năng độc lập với nhau và chỉ giao tiếp với nhau thông qua interface của nó. Abstraction là cách để giấu đi phần hiện thực của mỗi module mà chỉ cho module khác biết thông qua interface của nó. Trong module sẽ khai báo rõ phần nào thuộc interface, phần nào không thuộc interface. Các thành phần của module thường là variable, function, constant, class, object.
Ví dụ trong TypeScript:
module Log {
export class NormalLog {
function log(message) { console.log(message); }
} // interface - class
export function RegexLog(message) {
console.log(privateRegex + " " + message);
} // interface - function
Lập trình thủ tục rất linh động trong cách tạo interface. Bạn có thể tạo interface chỉ toàn là function như C hay áp dụng. Vì tính linh động đó quá mức khiến cho người viết app khó biết interface của module đó gồm những gì, có quy tắc nào để thống nhất nó không? Vì vậy người ta mới đề xuất OOP, giới hạn lại tính linh động của module.
OOP quản lý module bằng cách tập trung vào variable, constant và các hàm thao tác trên variable và constant đó. Và nó sẽ gom lại tạo thành 1 class, trong đó function được gọi khác là method.
Các từ khoá truy cập như public, protected, private sẽ xác định phạm vi interface của class. Inheritance thực chất là re-export. Bạn import từ 1 module (class), sau đó sửa đổi, và lại export module đó (class).
Với 1 chương trình OOP, hoàn toàn có cách để compile xuống thành chương trình thủ tục dễ dàng. Java là 1 ví dụ, Java là ngôn ngữ OOP, nhưng mã dịch bytecode của nó là hướng thủ tục, hàm của nó sẽ có dạng ClassName_functionName_paramType1_paramType2_…(objectName, param1, param2,…)
Chỗ này em thấy rất hay và đúng nữa (Y)