Lập trình có cấu trúc so với lập trình OO


11

Tôi đang trình bày cho thấy sự khác biệt giữa lập trình hướng đối tượng và cấu trúc và tôi muốn minh họa tại sao mọi người cần OOP với một ví dụ khi áp dụng các khái niệm OOP sẽ giúp mã hóa dễ dàng hơn để khán giả thực sự cảm thấy rằng họ cần OOP.

Bất kỳ ý tưởng ??


2
đặt câu hỏi này trên lập trình viên.stackexchange.com sẽ cho bạn nhiều câu trả lời hơn.
reggie

2
Khán giả của bạn là gì? Có kinh nghiệm lập trình viên không OO (cobol, vv)? lập trình viên ít kinh nghiệm (sinh viên, v.v.)? Giám đốc điều hành (không phải lập trình viên nào cả)?

Tôi đã không nghe về điều đó trước đây nhưng tôi đã đọc FAQ và tôi đoán tốt hơn nên hỏi ở đó.
Ahmed

kinh nghiệm thấp.
Ahmed

4
Tôi muốn một số chương trình OO được cấu trúc tốt hơn.
Scott Whitlock

Câu trả lời:


17

Bạn có thể muốn xem blog video nhanh này . Kết quả cuối cùng là sự khác biệt giữa lập trình có cấu trúc và lập trình OO là vấn đề họ lấy đi từ lập trình, chứ không phải về những gì họ thêm vào. Các ngành phần mềm như Lập trình có cấu trúc và Lập trình hướng đối tượng bị hạn chế, không cho phép. Dưới đây là một số định nghĩa. Cảnh báo: bạn sẽ không thích chúng.

  • Lập trình có cấu trúc là kỷ luật áp đặt khi goto (chuyển giao quyền kiểm soát trực tiếp)

  • Lập trình OO là kỷ luật áp đặt cho con trỏ đến các chức năng (chuyển giao quyền kiểm soát gián tiếp)

  • Lập trình chức năng là kỷ luật áp đặt khi giao.

    Điều đầu tiên không quá khó hiểu. Dijkstra nhận thấy rằng không thể tạo ra bằng chứng chung về tính đúng đắn khi goto được cho phép trong các thuật toán. Tuy nhiên, nếu các cấu trúc điều khiển bị giới hạn theo trình tự, lựa chọn và lặp lại, thì bằng chứng về tính chính xác có thể. Tất nhiên ngày nay chúng ta thậm chí không cố gắng chứng minh mọi thứ chính xác, nhưng chúng ta thích sự đơn giản và thanh lịch của lập trình có cấu trúc.

Khó hiểu hơn một chút về OO. Chúng ta thường định nghĩa OO là đóng gói, kế thừa và đa hình. Thế nào là ít biết là tất cả ba trong số những thuộc tính này là có thể đạt được, và thường xuyên được đạt được trong C. Thật vậy, C ++ bắt đầu như chỉ là một Preprocessor rằng biên soạn xuống C. Nó không thực sự khó khăn để đóng gói trong C. Cũng rất khó để xây dựng cấu trúc dữ liệu là tập hợp con của nhau, mô phỏng sự kế thừa. Đa hình, tuy nhiên, là một chút khó khăn hơn. Nó đòi hỏi con trỏ đến các chức năng, trong C, khó quản lý tốt. Những ngôn ngữ như C ++ đã cho chúng tôi là kỷ luật áp đặt cho những con trỏ đó vào các chức năng. Trình biên dịch C ++ đã xây dựng các vtables cho chúng ta và khởi tạo các con trỏ bên trong chúng theo một hình thức nghiêm ngặt. Vì vậy, theo một nghĩa rất thực, OO chỉ đơn giản là kỷ luật áp đặtchuyển gián tiếp điều khiển tức là con trỏ đến các chức năng.

Lập trình cấu trúc là về cách không sử dụng goto. OO là về cách không sử dụng con trỏ đến các chức năng. Và lập trình chức năng cũng là tất cả về những gì không nên làm. Trong lập trình chức năng, chúng tôi không gán các biến trừ trong các trường hợp được kiểm soát chặt chẽ nhất.

Vì vậy, cuối cùng, tất cả các "công nghệ" lập trình này thực sự đang hạn chế các quy tắc hơn là cho phép các công nghệ. Họ nói với chúng tôi những gì không nên làm nhiều hơn họ nói chúng tôi phải làm gì. Và điều đó có nghĩa là sự phát triển phần mềm đã không phát triển trong 40 năm qua. Thay vào đó, nó đã bị thu hẹp. Nó trở nên hạn chế hơn bao giờ hết khi chúng ta đã học được tất cả những điều chúng ta không nên làm.

Học những gì không nên làm là tốt; nhưng đây là câu hỏi làm phiền: Những tác vụ mới có chúng tôi đã học để làm gì?


@Ahmed: +1 cho "TL; DR, cảm ơn vì video" - bình luận thú vị (đùa)
n611x007

liên kết thối ... liên kết chết
slashdottir

7

Có 3 cách cơ bản để lập trình máy tính:

  1. Lập trình phi cấu trúc - với gotos, như trong các trình thông dịch BASIC cũ hoặc bằng ngôn ngữ hợp ngữ. Ít người lập trình theo cách này nữa.
  2. Lập trình mệnh lệnh có cấu trúc - như trong C, hoặc PASCAL.
  3. Lập trình chức năng có cấu trúc - như trong Haskell, ML hoặc Lisp.

Theo quan điểm của tôi, lập trình hướng đối tượng là một cái gì đó khác nhau. Đó là về cách tổ chức chương trình của bạn ở quy mô lớn hơn. Nó không thay thế hoặc lỗi thời trong bất kỳ 3 mô hình nào tôi đã đề cập ở trên - trong phần thân phương thức, bạn vẫn cần chọn một trong 3 mô hình từ danh sách để viết.


Tôi không hiểu bạn lắm! Ý bạn là chúng ta phải sử dụng một trong 3 mô hình nhưng CHÚNG TÔI không biết .. và OOP chỉ là về tổ chức nhiều hơn ??
Ahmed

Bạn không thể lập trình mà không học lập trình mệnh lệnh có cấu trúc hoặc lập trình chức năng có cấu trúc. Hai mô hình đó là về việc hoàn thành công việc. Mặt khác, OOP là về mô đun hóa chương trình chỉ phát huy tác dụng khi chương trình của bạn đạt đến một kích thước nhất định. Mặc dù nó chắc chắn xuất hiện trong các thư viện bạn sử dụng khi lập trình mọi lúc, nhưng người ta có thể có một thư viện lớp hoàn toàn tốt mà không có các tính năng OO như kế thừa, ví dụ như các thư viện lớp của Haskell, LISP hoặc Standard ML.
Ken Bloom

4

Đó là tất cả về cách bạn dự đoán sự thay đổi.

Cả hai khái niệm đều cho vay để tái sử dụng, nhưng OOP mở ra cơ hội cho những thay đổi dễ dàng hơn. OOP có tất cả khả năng sử dụng lại mà lập trình Kết cấu thực hiện, nhưng bạn cũng có thể sử dụng nó để tạo chức năng mới với ít nỗ lực hơn.

Bạn có thể nói rằng OOP kế thừa tất cả các chức năng của Lập trình cấu trúc với chức năng bổ sung của kế thừa! : -D


Tôi không thích thừa kế tại thời điểm này.

4
Tôi cũng vậy, nhưng đó là vì chính phủ đã tống cổ ông tôi ra khỏi lương hưu. Tuy nhiên, về mặt OOP, quyền thừa kế đã phục vụ tôi khá tốt!
corsiKa

Theo kinh nghiệm của tôi, kế thừa tốt nhất nên tránh trong OOP. Bạn có thường xuyên xây dựng một siêu lớp đối lập với Giao diện không? Thành phần ủng hộ như một quy tắc chung.
Janx

1
@Janx: "Bạn có thường xuyên xây dựng một siêu lớp trái ngược với Giao diện không?" Huh? Bạn không "xây dựng siêu lớp"; bạn lấy các lớp hiện có và xây dựng các lớp con từ chúng và bạn làm điều đó mọi lúc. Nếu bạn không sử dụng tính kế thừa, bạn sẽ không nhận được lợi ích của sự thay thế và đa hình Liskov, vậy bạn đang làm gì trong lập trình hướng đối tượng ở nơi đầu tiên? Thành phần là một công cụ khác nhau với trường hợp sử dụng khác nhau, không phải là sự thay thế cho thừa kế. Bạn không nên "ưu ái" cái này hơn cái kia; bạn nên sử dụng cả hai, mỗi cái cho những gì chúng hữu ích cho.
Mason Wheeler

1
@Mason - đáng chú ý là Barbara Liskov (của Nguyên tắc thay thế Liskov) thực sự đã nói (video dài) cô ấy không đặc biệt thích thừa kế.
Aidan Cully

2

Các khái niệm là trực giao. Lập trình có cấu trúc là về cấu trúc mã trong các thủ tục / hàm / phương thức. Hoàn toàn có thể (và mong muốn) tuân theo các nguyên tắc lập trình có cấu trúc trong các phương thức lớp khi thực hiện OOP.


1

Đó là một cách diễn đạt chủ quan - lập trình có cấu trúc và OOP là phong cách giải quyết vấn đề và không phải lúc nào cũng tốt hơn cách khác. Viết một thư viện phương thức số có ý nghĩa tốt nếu được thực hiện theo kiểu có cấu trúc, trong đó bạn đang thực hiện các biến đổi trên dữ liệu đầu vào. Tuy nhiên, một tác nhân đơn giản được điều khiển bởi một máy trạng thái có thể dễ dàng được biểu diễn dưới dạng một lớp độc lập trong Java hoặc C ++. OOP có thể là một cách tự nhiên để thể hiện các bộ lưu trữ cho các cấu trúc dữ liệu.

Nói về ẩn thông tin và mô đun hóa là một cách tốt để tự nhiên thúc đẩy OOP như một phong cách.

Một điều thú vị về vấn đề này đã được Steve Yegge viết lên - theo một số cách, một trong những mô tả tốt hơn về sự khác biệt trong cách tiếp cận giữa hai phong cách.


0

OOP dễ hiểu hơn khi bạn thực hiện mô hình kinh doanh. Khi bạn nghĩ về các yếu tố của ứng dụng, bạn sử dụng một số ĐỐI TƯỢNG và MỐI QUAN HỆ giữa chúng, ví dụ: Sách có Tác giả, Tiêu đề, ISBN. Sách là để cho vào Thư viện và có thể được mượn bởi Sinh viên. Lập trình cấu trúc thực thi suy nghĩ về các quy trình cụ thể, thực hiện không trừu tượng.

OOP được thiết kế để dễ dàng thay đổi. Thay đổi trong chương trình cấu trúc là có thể nhưng phải được mô tả bằng mã. Thay đổi trong chương trình OO có thể được mô tả bằng thay đổi mô hình trừu tượng.


0

Phạm vi biến đổi:

Tôi nghĩ rằng một nguyên tắc của các ngôn ngữ để đảm bảo lập trình tốt là hạn chế phạm vi của các biến. Trong các ngôn ngữ có cấu trúc như C, phạm vi chủ yếu có hai loại-

  • Phạm vi toàn cầu
  • Phạm vi cục bộ / hàm / phương thức

Chúng ta đều biết phạm vi toàn cầu là có hại. Nhưng đôi khi phạm vi địa phương không đủ để chạy chương trình. Tránh phạm vi toàn cầu sau đó có xu hướng sử dụng rộng rãi hơn các con trỏ, cho phép sử dụng các biến ngoài phạm vi. Nhưng con trỏ rất khó hiểu và sử dụng.

Các ngôn ngữ OOP như C ++ thêm một loại phạm vi mới Phạm vi lớp / Đối tượng thông qua đóng gói. Phạm vi này được tăng cường hơn nữa bởi các biến thể riêng tư / công cộng. Và điều này giải quyết nhiều vấn đề của phạm vi biến. Phạm vi được xác định rõ hơn trong OOP. Và con trỏ là ít cần thiết.

Đây là một trong những tính năng tuyệt vời của OOP.

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.