Ưu điểm của lập trình hướng đối tượng [đóng]


35

Lưu ý : câu hỏi này là một đoạn trích được chỉnh sửa từ một bài đăng blog tôi đã viết vài tháng trước. Sau khi đặt một liên kết đến blog trong một bình luận trên Lập trình viên. Có ai đó đã yêu cầu tôi gửi câu hỏi ở đây để họ có thể trả lời nó. Bài đăng này là phổ biến nhất của tôi, vì mọi người dường như gõ "Tôi không nhận được lập trình hướng đối tượng" vào Google rất nhiều . Hãy trả lời ở đây, hoặc trong một bình luận tại Wordpress.

Lập trình hướng đối tượng là gì? Không ai cho tôi một câu trả lời thỏa đáng. Tôi có cảm giác như bạn sẽ không nhận được một định nghĩa tốt từ một người nào đó xung quanh nói rằng đối tượng của Google và đối tượng hướng vào đối tượng với mũi của anh ấy trong không khí. Bạn cũng sẽ không nhận được một định nghĩa tốt từ một người không làm gì ngoài lập trình hướng đối tượng. Không ai hiểu cả lập trình hướng đối tượng và lập trình đã từng cho tôi một ý tưởng nhất quán về những gì một chương trình hướng đối tượng thực sự làm.

Ai đó có thể xin vui lòng cho tôi ý tưởng của họ về những lợi thế của lập trình hướng đối tượng?


2
Ôi, thật tuyệt - thật khó để đưa ra một định nghĩa mà mọi người nói họ làm OOP sẽ đồng ý! (Ngay cả việc bỏ bê những người thực sự chỉ đang làm, ví dụ lập trình thủ tục trong trang phục OOP.)
SamB

10
Nó thực sự nghe giống như "Tôi không có lập trình C. Chúng ta không thể sử dụng ngôn ngữ lắp ráp?" với tôi.
tia

2
@Joel: Tôi không nhất thiết phải biết những người đề xướng không hiểu biết giống như bạn, nhưng tôi nghĩ một phần tốt của nó có thể là họ được giới thiệu để lập trình bởi các lớp bằng ngôn ngữ OO. Nếu đó là đường cơ sở của bạn, bạn không hiểu làm thế nào đó là một bước tiến lên. Ngôn ngữ đầu tiên của tôi là Applesoft BASIC và tôi đã học được một số phương ngữ BASIC, cộng với C, Pascal và một chút lắp ráp x86 trước khi tôi được Delphi và C ++ giới thiệu với OOP. Những người đã trải nghiệm sự khác biệt có thể giải thích nó tốt hơn.
Mason Wheeler

3
Thêm ý kiến ​​tiêu cực về OOP tại đây: Harm.cat-v.org/software/OO_programming , bao gồm cả trích dẫn từ Dijkstra và Rob Pike.
imgx64

3
@Joel: Bạn đánh vào sự phản đối của tôi đối với OOP trên đầu. Những người đang OOP một-true-wayists thường có một cái nhìn rơm-người đàn ông của lập trình thủ tục và có ít hoặc không có kinh nghiệm trong bất kỳ mô hình khác ở tất cả. Lập trình hàm có vẻ hoàn toàn xa lạ với họ (bằng chứng: đếm số người gần đây hỏi cách làm các lớp và đối tượng trong Erlang vì một lý do kỳ quái nào đó) và lập trình logic sẽ làm nổ tung đầu của họ. Tôi chỉ có thể tưởng tượng những gì một số mô hình thực sự kỳ lạ sẽ làm với họ ....
CHỈ CẦN HOẠT ĐỘNG đúng

Câu trả lời:


7

Hãy nghĩ về phần mềm như một máy hoặc dây chuyền lắp ráp tồn tại bên trong máy tính. Một số nguyên liệu thô và các thành phần được đưa vào máy, và nó tuân theo một bộ quy trình để xử lý chúng thành một số sản phẩm cuối cùng. Các quy trình được thiết lập để thực hiện một thao tác cụ thể trên một số nguyên liệu thô hoặc thành phần cho một bộ thông số cụ thể (ví dụ: thời gian, nhiệt độ, khoảng cách, v.v.) theo một thứ tự cụ thể. Nếu chi tiết của thao tác được thực hiện không chính xác hoặc cảm biến của máy không được hiệu chuẩn chính xác hoặc nếu một số nguyên liệu thô hoặc thành phần không nằm trong tiêu chuẩn chất lượng dự kiến, nó có thể thay đổi kết quả của hoạt động và sản phẩm sẽ không thành công như mong đợi.

Một máy như vậy là rất cứng nhắc trong hoạt động của nó và đầu vào chấp nhận được. Máy móc không đặt câu hỏi về trí thông minh của nhà thiết kế cũng như môi trường hoạt động hiện tại của nó. Nó sẽ tiếp tục làm theo các thủ tục miễn là nó được hướng dẫn. Ngay cả khi một sự thay đổi trong nguyên liệu thô hoặc các thành phần có thể có tác động lớn đến những gì xảy ra trong các hoạt động sau này, máy vẫn sẽ thực hiện các quy trình của mình. Quá trình sẽ cần được xem xét để xem những thay đổi nào đối với các thủ tục là cần thiết để bù đắp và tạo ra kết quả mong muốn. Thay đổi về thiết kế hoặc cấu hình của sản phẩm cũng có thể yêu cầu thay đổi đáng kể đối với các hoạt động được thực hiện hoặc đơn đặt hàng của chúng. Mặc dù những người phụ trách sản xuất đã nhanh chóng học được tầm quan trọng của việc cô lập các hoạt động càng nhiều càng tốt để giảm các tác động không mong muốn giữa chúng, rất nhiều giả định được tạo ra từ các thành phần điều kiện khi chúng trải qua quá trình xử lý; các giả định có thể không được phát hiện cho đến khi sản phẩm cuối cùng nằm trong tay người dùng trong một số môi trường hoạt động khác nhau.

Đó là những gì lập trình thủ tục là như thế.

Những gì hướng đối tượng cung cấp là một cách để loại bỏ các giả định về tình trạng của các thành phần; do đó, các hoạt động được thực hiện trên thành phần đó và cách tích hợp nó vào sản phẩm cuối cùng. Nói cách khác, OOP giống như lấy các chi tiết quá trình để xử lý một số thành phần cụ thể và đưa nó cho một máy nhỏ hơn để làm. Máy lớn hơn chịu trách nhiệm cho quy trình cho máy cụ thể thành phần hoạt động mà nó dự kiến ​​sẽ được thực hiện nhưng để lại chi tiết cho các bước để máy cụ thể thành phần xử lý.

Về lợi thế của hướng đối tượng so với phần mềm không hướng đối tượng:

  • hành vi dành riêng cho thành phần - làm chi tiết về cách xử lý một thành phần cụ thể, trách nhiệm của máy cụ thể thành phần nhỏ hơn đảm bảo bất kỳ lúc nào thành phần đó được xử lý, máy của nó sẽ thực hiện một cách thích hợp;
  • biểu thức đa hình - bởi vì các máy cụ thể thành phần thực hiện các hoạt động được điều chỉnh theo thành phần cụ thể của nó, cùng một thông điệp được gửi đến các máy khác nhau có thể hoạt động khác nhau;
  • loại trừu tượng - thường có ý nghĩa đối với một số loại thành phần khác nhau để sử dụng cùng một từ vựng cho các hoạt động mà máy của chúng thực hiện;
  • tách các mối quan tâm - để lại các chi tiết cụ thể thành phần cho các máy của họ có nghĩa là máy xử lý chỉ cần xử lý các mối quan tâm chung hơn, lớn hơn của quy trình và dữ liệu cần thiết để quản lý nó; cộng với, nó ít có khả năng bị ảnh hưởng bởi những thay đổi trong các thành phần khác;
  • khả năng thích ứng - các thành phần tập trung vào lĩnh vực chuyên môn của họ có thể được điều chỉnh phù hợp với việc sử dụng không lường trước chỉ bằng cách thay đổi các thành phần mà nó sử dụng hoặc cung cấp cho máy xử lý khác;
  • tái sử dụng mã - các thành phần có trọng tâm hẹp và khả năng thích ứng lớn hơn có thể tận dụng chi phí phát triển của chúng bằng cách đưa vào sử dụng thường xuyên hơn.

3
Tất cả mọi thứ bạn nói dường như áp dụng như nhau cho lập trình chức năng, làm nổi bật vấn đề ở đây.
Jesse Millikan

1
Ngoại trừ OP không hỏi về lập trình chức năng, vì vậy bình luận của bạn thiếu công đức. Đặc biệt là vì câu trả lời của tôi là một trong những chấp nhận.
Huperniketes

Lập trình hàm tự nhiên gần với Định hướng đối tượng, trên thực tế, người ta có thể lập luận rằng lập trình hàm thực tế là một dạng định hướng đối tượng "thuần túy" hơn trong đó chính các hàm trở thành đối tượng hạng nhất. Tuy nhiên, vẫn là một người mới trong tất cả những thứ lập trình chức năng đó, tuy nhiên, đó là cảm giác của tôi lúc này.
Newtopian

46

Từ blog của bạn, có vẻ như bạn đã quen thuộc với cả lập trình bắt buộc và lập trình chức năng và bạn đã quen thuộc với các khái niệm cơ bản liên quan đến lập trình hướng đối tượng, nhưng bạn chưa bao giờ thực sự "nhấp chuột" như những gì làm cho nó hữu ích Tôi sẽ cố gắng giải thích theo kiến ​​thức đó và hy vọng rằng nó hữu ích cho bạn.

Về cốt lõi, OOP là một cách sử dụng mô hình bắt buộc để quản lý tốt hơn mức độ phức tạp cao bằng cách tạo các cấu trúc dữ liệu "thông minh" mô hình hóa miền vấn đề. Trong một chương trình (tiêu chuẩn không hướng đối tượng), bạn đã có hai điều cơ bản: biến và mã biết phải làm gì với chúng. Mã này lấy đầu vào từ người dùng và nhiều nguồn khác, lưu trữ nó trong các biến, vận hành trên nó và tạo dữ liệu đầu ra cho người dùng hoặc các vị trí khác.

Lập trình hướng đối tượng là một cách để đơn giản hóa chương trình của bạn bằng cách lấy mẫu cơ bản đó và lặp lại nó ở quy mô nhỏ hơn. Giống như một chương trình là một tập hợp lớn dữ liệu với mã biết phải làm gì với nó, mỗi đối tượng là một phần dữ liệu nhỏ được liên kết với mã để biết phải làm gì với nó.

Bằng cách chia nhỏ miền vấn đề thành các phần nhỏ hơn và đảm bảo càng nhiều dữ liệu càng tốt được liên kết trực tiếp với mã biết phải làm gì với nó, bạn sẽ dễ dàng suy luận về quy trình nói chung và cả về quy trình phụ. các vấn đề tạo nên quá trình.

Bằng cách nhóm dữ liệu vào các lớp đối tượng, bạn có thể tập trung mã liên quan đến dữ liệu đó, làm cho mã có liên quan dễ dàng hơn để tìm và gỡ lỗi. Và bằng cách đóng gói dữ liệu đằng sau các chỉ định truy cập và chỉ truy cập nó thông qua các phương thức, (hoặc thuộc tính, nếu ngôn ngữ của bạn hỗ trợ chúng), bạn sẽ giảm đáng kể khả năng tham nhũng dữ liệu hoặc vi phạm bất biến.

Và bằng cách sử dụng tính kế thừa và đa hình, bạn có thể sử dụng lại các lớp có sẵn, tùy chỉnh chúng để phù hợp với nhu cầu cụ thể của bạn, mà không phải sửa đổi bản gốc hoặc viết lại mọi thứ từ đầu. (Đó là điều bạn không bao giờ nên làm , nếu bạn có thể tránh nó.) Chỉ cần cẩn thận bạn hiểu đối tượng cơ sở của mình, hoặc bạn có thể kết thúc với chuột túi sát thủ .

Đối với tôi, đây là những nguyên tắc cơ bản của lập trình hướng đối tượng: quản lý phức tạp, tập trung mã và mô hình hóa miền vấn đề được cải thiện thông qua việc tạo các lớp đối tượng, kế thừa và đa hình, và tăng tính an toàn mà không mất sức mạnh hoặc kiểm soát thông qua việc sử dụng đóng gói và tính chất. Tôi hy vọng điều này giúp bạn hiểu tại sao rất nhiều lập trình viên thấy nó hữu ích.

EDIT: Trả lời câu hỏi của Joel trong các bình luận,

Bạn có thể giải thích "chương trình hướng đối tượng" chứa gì (ngoài những khiếm khuyết ưa thích mà bạn đã vạch ra) về cơ bản khác với một chương trình bắt buộc không? Làm thế nào để bạn "có được quả bóng lăn?"

Một chút từ chối ở đây. Mô hình "chương trình hướng đối tượng" của tôi về cơ bản là mô hình Delphi, rất giống với mô hình C # /. NET do chúng được tạo bởi các thành viên nhóm Delphi trước đây. Những gì tôi đang nói ở đây có thể không áp dụng, hoặc không áp dụng nhiều như vậy, trong các ngôn ngữ OO khác.

Một chương trình hướng đối tượng là một chương trình trong đó tất cả logic được cấu trúc xung quanh các đối tượng. Tất nhiên điều này phải được bootstrapping ở đâu đó. Chương trình Delphi điển hình của bạn chứa mã khởi tạo tạo một đối tượng singleton được gọi Application. Khi bắt đầu chương trình, nó gọi Application.Initialize, sau đó gọi đến Application.CreateFormmọi hình thức bạn muốn tải vào bộ nhớ từ đầu, sau Application.Run,đó hiển thị biểu mẫu chính trên màn hình và khởi động vòng lặp đầu vào / sự kiện tạo thành lõi của bất kỳ chương trình máy tính tương tác.

Ứng dụng và biểu mẫu của bạn thăm dò các sự kiện đến từ HĐH và dịch chúng thành các cuộc gọi phương thức trên đối tượng của bạn. Một điều rất phổ biến là việc sử dụng các trình xử lý sự kiện hoặc "đại biểu" trong .NET-speak. Một đối tượng có một phương thức cho biết, "thực hiện X và Y, nhưng cũng kiểm tra xem liệu trình xử lý sự kiện cụ thể này có được chỉ định hay không và gọi nó nếu có." Trình xử lý sự kiện là một con trỏ phương thức - một bao đóng rất đơn giản chứa tham chiếu đến phương thức và tham chiếu đến thể hiện đối tượng - được sử dụng để mở rộng hành vi của các đối tượng. Ví dụ: nếu tôi có một đối tượng nút trên biểu mẫu của mình, tôi sẽ tùy chỉnh hành vi của nó bằng cách đính kèm một trình xử lý sự kiện OnClick, điều này khiến một số đối tượng khác thực thi một phương thức khi nhấp vào nút.

Vì vậy, trong một chương trình hướng đối tượng, hầu hết các công việc được thực hiện bằng cách xác định các đối tượng với một số trách nhiệm nhất định và liên kết chúng với nhau, thông qua các con trỏ phương thức hoặc bằng một đối tượng gọi trực tiếp một phương thức được xác định trong giao diện chung của đối tượng khác. (Và bây giờ chúng tôi quay lại đóng gói.) Đây là một ý tưởng mà tôi không có khái niệm trở lại trước khi tôi tham gia các lớp học OOP ở trường đại học.


4
Tôi nghĩ rằng bạn thực sự đánh vào đầu với câu trả lời này. Khi bạn đóng gói thao tác dữ liệu (OK, họ đang phân bổ một con trỏ ở đây và sau đó dịch chuyển một vài bit ở đó ...) tất cả những gì còn lại là logic mức cao của chương trình (Nếu được thực hiện đúng cách, bạn có thể viết mã khủng khiếp trong bất kỳ mô hình nào .) .
ChaosPandion

2
Đó là một lời giải thích tuyệt vời, cảm ơn bạn. Bạn có thể giải thích "chương trình hướng đối tượng" chứa gì (ngoài những khiếm khuyết ưa thích mà bạn đã vạch ra) về cơ bản khác với một chương trình bắt buộc không? Làm thế nào để bạn "có được quả bóng lăn?"
Joel J. Adamson

1
+1: Tôi nghĩ rằng bạn thực sự đã hiểu nó với "về cơ bản là cố gắng lặp lại những điều tương tự ở quy mô nhỏ hơn", về cơ bản là một mức độ trừu tượng khác (hoặc tốt hơn, giống như một mức độ khác có thể để tạo ra sự trừu tượng).
n1ckp

1
@Karthik Một chút muộn cho bữa tiệc, nhưng thực sự là không, OOP không có nghĩa là chỉ sử dụng lại các lớp. Toàn bộ khái niệm của một hệ thống loại là một sự trừu tượng để nhóm các đối tượng lại với nhau theo các giao diện chung. Nhưng bạn cũng có thể sử dụng một hệ thống dựa trên nguyên mẫu (như Javascript) trong đó phương thức gọi đối tượng giải quyết chuỗi nguyên mẫu thay vì lên chuỗi lớp. Nó vẫn có tất cả các tính năng của OOP, nhưng cho phép các đối tượng và loại đặc biệt bằng cách thêm các công cụ mới vào một đối tượng hiện có. Sau đó, bạn có thể sao chép đối tượng đó để có thêm loại mới đó.
CodexArcanum

2
+1 để chỉ ra lợi thế thực sự của OOP. "Về cốt lõi, OOP là một cách sử dụng mô hình bắt buộc để quản lý tốt hơn mức độ phức tạp cao bằng cách tạo các cấu trúc dữ liệu" thông minh "mô hình hóa miền vấn đề."
Karthik Sreenivasan

6

Tôi nghĩ rằng OOP về cơ bản chỉ là một cái tên được đặt cho một cái gì đó mà bạn có thể đã bị cám dỗ để làm trên đường đi, như tôi đã từng.

Quay trở lại khi tôi còn là một lập trình viên nhí, ngay cả ở Fortran, có một thứ giống như một con trỏ đến chương trình con. Nó thực sự hữu ích khi có thể truyền một con trỏ đến chương trình con làm đối số cho chương trình con khác.

Sau đó, điều tiếp theo sẽ thực sự hữu ích là lưu trữ một con trỏ đến chương trình con bên trong bản ghi cấu trúc dữ liệu. Bằng cách đó, bạn có thể nói bản ghi "biết" cách tự thực hiện các thao tác.

Tôi không chắc họ đã từng xây dựng nó thành Fortran chưa, nhưng thật dễ dàng để làm ở C và hậu duệ của nó.

Vì vậy, bên dưới, đó là một ý tưởng đơn giản và hữu ích mà bạn có thể muốn tự làm, và dễ dàng thực hiện bằng các ngôn ngữ gần đây hơn, ngay cả khi một số người biến nó thành một nhóm nhạc khổng lồ đầy những từ thông dụng đáng sợ.


5

Có nhiều loại hệ thống OO khác nhau và thật khó để có một định nghĩa mà mọi người sẽ đồng ý. Thay vì cố gắng chỉ ra cách OO của Java tương tự như Hệ thống đối tượng Lisp chung, tôi sẽ bắt đầu với một cái gì đó thông thường hơn, từng bước một.

Giả sử bạn có rất nhiều đối tượng tồn tại dưới dạng dữ liệu phân tán. Các điểm, ví dụ, có thể là các phần tử trong một mảng X, Y và Z. Để xem xét một điểm riêng của mình, nó làm cho tinh thần để kéo tất cả các dữ liệu lại với nhau thành một cái gì đó giống như một C struct.

Bây giờ, đối với bất kỳ đối tượng dữ liệu nào, chúng ta đã có dữ liệu cùng nhau. Tuy nhiên, trong một chương trình thủ tục, mã bị phân tán. Giả sử chúng ta đang xử lý các hình dạng hình học. Có một chức năng lớn để vẽ các hình dạng, và nó cần biết về tất cả các hình dạng. Có một chức năng lớn để tìm diện tích và một chức năng khác cho chu vi. Mã cho một vòng tròn được phân tán thông qua nhiều chức năng và để thêm một loại hình dạng khác, chúng ta cần biết những chức năng nào sẽ thay đổi. Trong một hệ thống hướng đối tượng, chúng tôi tập hợp các hàm thành cùng loại classdữ liệu ( ) với dữ liệu. Do đó, nếu chúng ta muốn xem tất cả các mã vòng tròn, nó có trong Circleđịnh nghĩa và nếu chúng ta muốn thêm một Quartercirclelớp, chúng ta chỉ cần viết lớp của nó và chúng ta đã có mã.

Một lợi ích từ việc này là chúng ta có thể duy trì các bất biến của lớp, những điều đúng với từng thành viên của lớp. Bằng cách hạn chế mã bên ngoài lớp không gây rối trực tiếp với các thành viên dữ liệu của lớp, chúng tôi đã có tất cả mã có thể thay đổi dữ liệu của lớp ở một nơi và chúng tôi có thể xác nhận rằng nó không làm bất cứ điều gì khó khăn (như có một hình tam giác với một chân dài hơn hai cái kia cộng lại). Điều này có nghĩa là chúng ta có thể tin tưởng vào một số thuộc tính của mọi thành viên trong lớp và không phải kiểm tra xem liệu một đối tượng có lành mạnh mỗi khi chúng ta sử dụng nó không.

Lợi ích chính đi kèm với sự kế thừa và đa hình. Bằng cách định nghĩa tất cả các hình dạng khác nhau này là các lớp con của một lớp được gọi Shape, chúng ta có thể điều khiển mã Shapecủa mình và đó là công việc của các tiểu dự án hình dạng để làm bất cứ điều gì được yêu cầu bởi các thao tác. Điều này có nghĩa là chúng ta không cần phải chạm vào mã đã kiểm tra cũ khi chúng ta thêm hình dạng mới hoặc tinh chỉnh hành vi của những cái cũ hơn. Chúng tôi tự động có mã cũ có thể trực tiếp tận dụng mã mới. Thay vì làm cho mã điều khiển nhận biết tất cả các hình dạng có thể khác nhau và phải duy trì các chức năng nhận biết tất cả các hình dạng khác nhau có thể, chúng tôi chỉ xử lý các hình dạng và thuộc tính của chúng, trong khi duy trì các Shapelớp con. Điều này đơn giản hóa mã kiểm soát.

Chúng tôi có một số lợi thế ở đây. Vì chúng ta có các bất biến lớp, chúng ta có thể suy luận về các đối tượng dữ liệu lớn hơn giống như cách chúng ta suy luận về các kiểu dựng sẵn, có nghĩa là chúng ta thường có thể chia các khái niệm phức tạp thành các khái niệm đơn giản hơn. Vì mã vòng tròn chủ yếu được chứa trong Circle, chúng tôi đã tăng địa phương. Vì không có khái niệm về một vòng tròn nằm rải rác qua một số chức năng khác nhau ở những nơi khác nhau, chúng tôi ít có sự kết hợp giữa các thói quen và không phải lo lắng về việc giữ chúng đồng bộ. Vì các lớp, về mặt hiệu quả, các loại, chúng ta có thể tận dụng hệ thống loại hiện có để bắt sử dụng các lớp của chúng ta không tương thích.


3

OO có nhiều định nghĩa khác nhau, vâng. Tôi chắc rằng bạn có thể tự mình tìm thấy rất nhiều thứ này. Cá nhân tôi thích Rees Re: OO như một cách để hiểu ý nghĩa của chúng. Tôi đoán bạn đã đọc nó từ khi bạn trích dẫn Paul Graham. (Tôi giới thiệu nó cho bất kỳ ai quan tâm đến OO.) Tôi sẽ ít nhiều chấp nhận định nghĩa Java tại đây {1,2,3,7,8,9}.

Câu hỏi về tiện ích của OO, đặc biệt là cách tôi tiếp cận nó, xứng đáng có câu trả lời lớn hơn nhiều với vài nghìn dòng mã (một phần để không chỉ là một loạt các xác nhận). Tuy nhiên, đây là một bản tóm tắt của tài liệu giả định đó.

Tôi không nghĩ rằng OO rất hữu ích ở quy mô nhỏ, khoảng vài trăm dòng. Cụ thể, các ngôn ngữ OO không có ảnh hưởng chức năng tốt có xu hướng làm cho nó thực sự đau đớn khi thực hiện những điều đơn giản với bất kỳ loại bộ sưu tập hoặc bất cứ thứ gì cần nhiều loại dữ liệu. Đây là nơi mà hầu hết các mẫu thiết kế đi vào chơi; họ là những người hỗ trợ ban nhạc với sức mạnh thấp của ngôn ngữ cơ bản .

Ở khoảng một nghìn dòng, bắt đầu khó theo dõi tất cả các hoạt động và cấu trúc dữ liệu và cách chúng liên quan. Tại thời điểm này, nó giúp có cách tổ chức rõ ràng các cấu trúc và hoạt động dữ liệu, vẽ ranh giới mô-đun và xác định trách nhiệm và có một cách thuận tiện để hiểu các định nghĩa đó trong khi bạn đang cố gắng lập trình chống lại chúng.

Java-ish OO là một giải pháp nửa chừng cho những vấn đề này đã giành chiến thắng trong cuộc thi phổ biến. Bởi vì đó là cùng một cơ chế mà người Java áp dụng cho các vấn đề quy mô nhỏ được tạo ra bởi một ngôn ngữ không đủ sức mạnh, nên nó có xu hướng bắt đầu giống như một giải pháp kỳ diệu cho mọi thứ hơn là một cách để tổ chức. Những người quen thuộc với lập trình chức năng có xu hướng thích các giải pháp khác, như các lớp loại của CLOS hoặc Haskell, hoặc siêu lập trình mẫu khi bị mắc kẹt trong C ++, hoặc người khác (như tôi, làm việc hàng ngày trong C #) sử dụng OO nhưng không cảm thấy phấn khích về nó .


+1 - Câu trả lời tuyệt vời. "Tôi không nghĩ OO rất hữu ích ở quy mô nhỏ."
Karthik Sreenivasan

Tôi thậm chí đã đọc một bài viết ( dl.acm.org/citation.cfm?id=326103 ) nói rằng OOP không hiển thị bất kỳ lợi thế năng suất thực sự nào đối với thủ tục cho hai bản phát hành đầu tiên của sản phẩm phần mềm. Theo tôi hiểu, chỉ bắt đầu từ phiên bản thứ ba, bạn có lợi thế thực sự bởi vì bạn có thể tái sử dụng / tái cấu trúc mã tốt hơn được viết theo kiểu OO hơn là theo kiểu thủ tục.
Giorgio

1

OOP cố gắng mô hình hóa các khái niệm trong thế giới thực về các đối tượng và tương tác giữa chúng. Là con người, chúng ta có xu hướng xử lý thế giới về các đối tượng. Thế giới có đầy đủ các đối tượng có các thuộc tính nhất định và có thể thực hiện các công việc như tương tác với các đối tượng khác. OOP cho phép mô hình hóa thế giới theo cách tương tự. Ví dụ,

  • Người là một đối tượng. Một người có một số tính chất, như tuổi tác và giới tính. Một người có thể làm những việc: ăn, ngủ, lái xe.
  • Xe cũng là một đối tượng (mặc dù thuộc loại khác nhau). Nó cũng có các thuộc tính như make, model và năm. Một chiếc xe có thể làm những việc: di chuyển.

Nhưng một chiếc xe không thể tự di chuyển, nó cần một người lái nó - sự tương tác giữa các Đối tượng.


Tôi hiểu rồi: điều đó có ý nghĩa Tuy nhiên, tôi nghĩ một trong những điều thực sự thú vị khi lập trình máy tính là chúng ta không phải suy nghĩ về cách các đối tượng "thế giới thực" làm mọi việc. Tôi nghĩ toán học nhiều hơn (Tôi là một nhà toán học làm nghiên cứu sinh học). Đây là một "a-ha" (một cái nhìn sâu sắc về thiền định), không phải là một thái độ đi vào. Tuy nhiên, nó đã ảnh hưởng lớn đến cách tôi làm công việc của mình.
Joel J. Adamson

1

OOP = cấu trúc dữ liệu + truyền thông điệp + kế thừa, tất cả đều là các diễn biến logic trong các mô hình lập trình.

OOP có thể được hiểu (bởi các lập trình viên) trong khoảng 90 giây (xem hồ sơ của tôi để biết liên kết). Các khái niệm rất đơn giản.

Làm thế nào để áp dụng nó là một vấn đề khác. Chỉ vì bạn biết cách vung búa không có nghĩa là bạn biết cách thiết kế và xây dựng một ngôi nhà. ;-)


+1 - Tôi đồng ý. Làm thế nào để áp dụng OOP mất rất nhiều thời gian và thực tế mặc dù chỉ cần biết những gì họ đã không mất nhiều thời gian vì hàm ý là từ khóa ở đây.
Karthik Sreenivasan

0

Tôi đã viết một bài đăng blog cách đây một thời gian mà bạn có thể thấy hữu ích: Giải thích so với OOP Giải thích .


Tôi không biết tại sao mọi người bỏ phiếu xuống! Bài viết này là tốt hơn sau đó tất cả các bên trên cùng nhau! phiếu bầu của tôi cho +1
Haris

Nó đã bỏ phiếu xuống vì nó chỉ là một liên kết và chạy, điều này rất nản lòng. Xem câu hỏi meta stackoverflow: Các câu trả lời chỉ chứa các liên kết ở nơi khác có thực sự là câu trả lời hay không?
icc97

0

Cách đầu tiên tôi hiểu nó là:

Trước khi lập trình hướng đối tượng, bạn đã lập trìnhcấu trúc . Tất cả mọi thứ được tập trung xung quanh quá trình. Câu hỏi đầu tiên bạn phải tự hỏi mình là " Tôi muốn làm gì với thông tin? ".

Với lập trình hướng đối tượng, nó tập trung vào dữ liệu. Câu hỏi đầu tiên bạn phải tự hỏi mình là " Thông tin phù thủy tôi cần phải giải quyết? ". Điều này làm cho sự trừu tượng dễ dàng hơn.


0

Vì bạn hiểu các cấu trúc và bạn hiểu các con trỏ hàm và bạn hiểu các cấu trúc với các con trỏ hàm, từ quan điểm của bạn, tôi sẽ định nghĩa lập trình hướng đối tượng là "lập trình, với việc sử dụng nhiều các cấu trúc có con trỏ hàm". Nó vẫn lập trình theo nghĩa truyền thống - đó là tất cả dữ liệu và mã hoạt động theo dữ liệu. Sự khác biệt chỉ đơn giản là cách tất cả các thông tin đó được xác định và cách bạn tiếp cận xác định nó.

Có lẽ một sự đơn giản hóa quá mức là lập trình truyền thống là "mã, với một số cấu trúc dữ liệu" và lập trình hướng đối tượng là "cấu trúc dữ liệu, với một số mã". Cả hai vẫn có cấu trúc dữ liệu và cả hai vẫn có mã. Do đó, lập trình hướng đối tượng không gì khác hơn là hành động xác định các loại dữ liệu trước và thực thi các hợp đồng về cách chúng giao tiếp thông qua các bộ chức năng.

Như bạn đã quan sát, có một lớp ứng dụng khổng lồ mà đây không phải là cách tuyệt vời để thực hiện giải pháp. Bạn dường như sống trong một thế giới chủ yếu được tạo thành từ các ứng dụng như vậy. Trong bài đăng trên blog của bạn, bạn đề cập đến việc xem xét triển khai vấn đề "99 chai bia" ("chương trình giới thiệu yêu thích" của bạn). 99 chai bia chắc chắn là một phần của thể loại đó. Cố gắng hiểu lập trình hướng đối tượng bằng cách xem xét việc triển khai 99 chai bia giống như cố gắng hiểu kiến ​​trúc nhà cao tầng bằng cách nhìn vào một ngôi nhà trên cây. Ngay cả một ngôi nhà trên cây được xây dựng rất tốt cũng chỉ có thể dạy bạn rất nhiều.

TL; DR: Lập trình OO giống như lập trình truyền thống, ngoại trừ bạn tập trung nhiều nỗ lực hơn vào việc xác định cấu trúc dữ liệu trước và bạn có các cấu trúc dữ liệu đó giao tiếp với nhau thông qua các con trỏ hàm.


-1

Tôi nghĩ rằng trang Wikipedia là một nơi tốt để có được các nguyên tắc cơ bản:
http://en.wikipedia.org/wiki/Object-oriented_programming

Về cơ bản, ý tưởng là lập trình thủ tục, đó là điều mà OOP đang cố gắng cải thiện, tập trung vào các quy trình đang được mô hình hóa. OOP chuyển sang một mô hình trong đó trọng tâm là "những thứ" bạn đang lập mô hình, và các quy trình và dữ liệu của những thứ đó được chứa trong những thứ đó.

Vì vậy, ví dụ, giả sử bạn đang thiết kế một ứng dụng để theo dõi danh sách nhiệm vụ. Trong lập trình thủ tục, các thực thể cấp cao nhất của bạn trong mô hình sẽ là các quá trình xảy ra, chẳng hạn như tạo một tác vụ, xóa một tác vụ, thay đổi thông tin nhiệm vụ, v.v. Trong mô hình OOP, thay vào đó bạn sẽ tập trung vào việc tạo một Tác vụ và nghĩ về những dữ liệu và quy trình mà Nhiệm vụ phải chịu trách nhiệm. Và sau đó tập trung vào những đối tượng khác mà Nhiệm vụ nên tương tác, chẳng hạn như Ghi chú hoặc thứ gì đó nếu bạn muốn ghi chú về Nhiệm vụ.

Tôi hy vọng điều đó sẽ giúp. Chỉ cần tiếp tục đọc về nó và nhìn vào mã và nó sẽ đột nhiên "nhấp chuột". Đó là kinh nghiệm của tôi.


Downvoter quan tâm để đưa ra một lý do?
RationalGeek

Có vẻ như bạn thậm chí chưa đọc toàn bộ câu hỏi được hỏi, ít bị chọc vào mục blog được liên kết. Tác giả không có vấn đề gì với các nguyên tắc cơ bản, theo như tôi có thể nói. Vì vậy, về cơ bản, -1 để trả lời một câu hỏi bạn muốn trả lời thay vì câu hỏi đang được hỏi.
Jesse Millikan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.