Lập trình chức năng so với OOP [đã đóng]


93

Tôi đã nghe nói rất nhiều về việc sử dụng các ngôn ngữ chức năng như Haskell vào cuối. Một số khác biệt lớn, ưu và nhược điểm của lập trình chức năng so với lập trình hướng đối tượng là gì?


27
Người ta không từ chối người khác.
mbq

1
@mbq Tôi hiểu rằng họ không loại trừ lẫn nhau, nhưng tôi chỉ muốn cố gắng hiểu rõ hơn về sự khác biệt của hai phương pháp.
GSto

Câu hỏi tuyệt vời. Tôi cũng đã tự hỏi về điều này.
JohnFx

Lập trình chức năng và lập trình hướng đối tượng là trực giao với nhau. Bạn có thể có cả hai trong cùng một ngôn ngữ. Ví dụ: Scala, F #, OCaml, v.v. Có lẽ bạn có nghĩa là chức năng so với mệnh lệnh, như Jonas đề xuất ?
missingfaktor

4
Câu trả lời thực sự là - không có "so với" giữa chúng. Kiểm tra câu hỏi này tại StackOverflow .
missingfaktor

Câu trả lời:


67

Tôi muốn nói rằng đó là lập trình chức năng nhiều hơn so với lập trình mệnh lệnh .

Sự khác biệt lớn nhất là lập trình mệnh lệnh là về luồng điều khiển trong khi lập trình hàm là về luồng dữ liệu . Một cách khác để nói rằng đó là lập trình chức năng chỉ sử dụng các biểu thức trong khi trong lập trình mệnh lệnh cả biểu thứccâu lệnh đều được sử dụng.

Ví dụ, trong các biến lập trình bắt buộc và các vòng lặp là phổ biến khi xử lý trạng thái, trong khi trong lập trình chức năng , trạng thái được xử lý thông qua truyền tham số, tránh tác dụng phụ và bài tập.

Mã giả bắt buộc cho một hàm để tính tổng của một danh sách (tổng được giữ trong một biến):

int sumList(List<int> list) {
    int sum = 0;
    for(int n = 0; n < list.size(); n++) {
        sum = sum + list.get(n);
    }

    return sum;
}

Mã giả chức năng cho cùng một chức năng (tổng được truyền dưới dạng tham số):

fun sumList([], sum) = sum
 |  sumList(v::lst, sum) = sumList(lst, v+sum)

Tôi khuyên bạn nên trình bày Hiệu ứng thuần hóa với lập trình chức năng của Simon Peyton-Jones để giới thiệu tốt về các khái niệm chức năng.


12
Bạn nên đề cập rằng phiên bản chức năng là đệ quy đuôi và do đó được tối ưu hóa để tránh tràn ngăn xếp. (Một số người có thể thấy đệ quy và nghĩ rằng lập trình chức năng là xấu vì nó)
thay thế

3
+1 để mô tả khía cạnh quan trọng nhất của mệnh lệnh so với chức năng: luồng điều khiển so với luồng dữ liệu. Một điều tôi phải nói thêm là mô hình chức năng và mô hình OO không loại trừ lẫn nhau; bạn có thể sử dụng mô hình OO để mô hình hóa cách đối tượng (dữ liệu) tương tác và mô hình chức năng để biến đổi (thao tác) đối tượng đó.
Lie Ryan

1
Thật thú vị, bạn có thể mô hình hóa dữ liệu dưới dạng kiểm soát và kiểm soát dưới dạng dữ liệu để xen kẽ. FP có thể sử dụng Mũi tên và các hàm thứ tự đầu tiên để truyền luồng điều khiển xung quanh và thao tác với nó như dữ liệu. OOP sử dụng các mẫu thiết kế khác nhau để sử dụng các đối tượng để thay đổi luồng điều khiển.
CodexArcanum

Tôi nghĩ cũng đáng lưu ý rằng sự khác biệt chính không phải là bạn viết cùng một chương trình mà là bạn thực hiện các cuộc gọi phương thức đệ quy theo vòng lặp. nó lớn hơn thế
sara

Ví dụ chức năng của bạn sử dụng khớp mẫu tham số. Điều đó không dành riêng cho lập trình chức năng, các chương trình chức năng tương tự có thể sử dụng các đơn nguyên và thậm chí các cấu trúc giống như mệnh lệnh mà không nhất thiết phải xây dựng mọi thuật toán lặp như một thuật toán đệ quy.
Đại

16

Lập trình hàm dựa trên mô hình khai báo và có nguồn gốc từ phép tính lambda. Nó cung cấp rất nhiều khái niệm tuyệt vời có thể được mượn từ các ngôn ngữ cấp bách hơn như C ++ và C #.

Một số ví dụ bao gồm tính minh bạch tham chiếu, chức năng lambda, chức năng hạng nhất, đánh giá lười biếng và háo hức, và bất biến.

Nếu không có gì khác thì học lập trình chức năng là hữu ích cho các khái niệm mà nó chứa. Nó sẽ thay đổi cách bạn lập trình và suy nghĩ về lập trình. Và tôi đoán rằng trong tương lai lập trình chức năng sẽ quan trọng như lập trình hướng đối tượng.

Để bắt đầu, bạn có thể chọn sử dụng ngôn ngữ chức năng thuần túy như Haskell hoặc bạn có thể sử dụng ngôn ngữ lai như F # .

Hầu hết các trường đại học tốt sẽ bao gồm chương trình chức năng và nếu bạn đi học, tôi rất khuyên bạn nên tham gia khóa học đó.


Một số khác biệt lớn, ưu và nhược điểm của lập trình chức năng so với lập trình hướng đối tượng là gì?

Lập trình hướng đối tượng tốt là tốt vì nó cho phép bạn mô hình hóa vấn đề phức tạp của mình thành các hệ thống phân cấp để bạn có thể đơn giản hóa vấn đề. Nhưng nó trở nên rất khó khăn khi bạn bắt đầu xem xét lập trình đa luồng trong khi sử dụng các đối tượng có thể thay đổi. Trong những trường hợp như vậy, bạn cần sử dụng nhiều đối tượng đồng bộ hóa và gần như không thể hoàn thiện một ứng dụng lớn.

Đó là nơi lập trình chức năng xuất hiện. Bởi vì những thứ như lập trình chức năng bất biến thực sự đơn giản hóa các chương trình đa luồng. Nó giúp việc song song hóa một thứ gì đó gần như dễ dàng khi bạn biết rằng đầu vào X cho một hàm, nó sẽ luôn xuất Y. Ngoài ra, bạn biết rằng một biến (hoặc giá trị trong lập trình hàm) không thể thay đổi sử dụng giữa từ một luồng khác.


2
Rõ ràng, Scheme hoàn toàn không phải là một ngôn ngữ chức năng thuần túy.
Jonathan Sterling

5
Đoạn cuối thứ hai của bạn là hoàn toàn bs. OO không đặt ra bất kỳ vấn đề nào trong đa luồng, khả năng biến đổi. Bạn dường như đang nhầm lẫn giữa lập trình mệnh lệnh với lập trình hướng đối tượng. Có phải vậy không?
missingfaktor

5
@missingfaktor: Không, tôi không nhầm lẫn các khái niệm. Một đối tượng thường có bộ truy cập, bộ sửa đổi, thành viên dữ liệu và chức năng thành viên. Có, không phải tất cả các đối tượng cần phải có sửa đổi và bạn có thể thực hiện chúng là bất biến. Nhưng nếu bạn nhìn vào bất kỳ chương trình OO tùy ý nào, nó gần như chắc chắn sẽ có một vài đối tượng có bộ sửa đổi và vẫn được sử dụng bởi nhiều luồng. Tức là trong một mô hình OOP, thật hiếm khi có mọi thứ bất biến.
Brian R. Bondy

Bạn nên đọc câu trả lời cho câu hỏi này: stackoverflow.com/questions/3949618/fp-and-oo-orthogonal/
Kẻ

Ngoài ra, hãy kiểm tra câu trả lời của Frank Shearar tại đây: lập trình
viên.stackexchange.com/questions/12423 / Fiêu

8

(Câu trả lời này được điều chỉnh từ câu trả lời cho câu hỏi đóng tại StackOverflow .)

Một trong những khác biệt lớn giữa lập trình chức năng và lập trình hướng đối tượng là mỗi cái tốt hơn ở một loại tiến hóa phần mềm khác nhau:

  • Các ngôn ngữ hướng đối tượng là tốt khi bạn có một tập hợp hoạt động cố định trên mọi thứ và khi mã của bạn phát triển, bạn chủ yếu thêm những thứ mới. Điều này có thể được thực hiện bằng cách thêm các lớp mới thực hiện các phương thức hiện có và các lớp hiện có được để lại một mình.

  • Các ngôn ngữ chức năng là tốt khi bạn có một tập hợp các thứ cố định và khi mã của bạn phát triển, bạn chủ yếu thêm các hoạt động mới vào những thứ hiện có. Điều này có thể được thực hiện bằng cách thêm các hàm mới tính toán với các kiểu dữ liệu hiện có và các hàm hiện có được để riêng.

Khi tiến hóa đi sai hướng, bạn có vấn đề:

  • Thêm một hoạt động mới vào một chương trình hướng đối tượng có thể yêu cầu chỉnh sửa nhiều định nghĩa lớp để thêm một phương thức mới.

  • Thêm một loại điều mới vào một chương trình chức năng có thể yêu cầu chỉnh sửa nhiều định nghĩa hàm để thêm trường hợp mới.

Vấn đề này đã được biết đến trong nhiều năm; vào năm 1998, Phil Wadler đã gọi nó là "vấn đề biểu hiện" . Mặc dù một số nhà nghiên cứu nghĩ rằng vấn đề biểu hiện có thể được giải quyết với các tính năng ngôn ngữ như mixins, một giải pháp được chấp nhận rộng rãi vẫn chưa được đưa vào dòng chính.


Tôi yêu câu trả lời của bạn, lời khôn ngoan ở đây. Tôi đã gặp nó vài tháng trước và chỉ dành 30 phút để tìm kiếm nó vì tôi đã không đánh dấu nó. Chỉ là lời giải thích tốt nhất về OOP vs FP cho những người hiểu lợi thế của việc hiểu các khái niệm hơn là các kỹ thuật. Bài viết về vấn đề biểu hiện cũng tuyệt vời. Cảm ơn rất nhiều vì đã chia sẻ cái nhìn sâu sắc của bạn, câu trả lời của bạn rất bị đánh giá thấp theo ý kiến ​​của tôi.
tobiak777

4

Không có thực so với. Họ có thể được bổ sung hoàn hảo. Có các ngôn ngữ FP, hỗ trợ OOP. Nhưng các cộng đồng khác nhau trong cách họ xử lý mô-đun.

Người dùng ngôn ngữ FP có xu hướng đạt được mô đun hóa thông qua các định luật toán học. Và thích bằng chứng để thể hiện sự tuân thủ pháp luật của họ.

Trong OOP bắt buộc, người dùng có xu hướng nắm bắt hành vi của đối tượng trong các trường hợp thử nghiệm, có thể chạy lại nếu đối tượng đã thay đổi và đạt được theo cách mô đun hóa này.

Nó chỉ là một khía cạnh nhỏ, nhưng tôi nghĩ nó đáng được đề cập.


2

Một sự tương tự:

Bạn đang trao một đơn xin việc. Bạn điền tên, thông tin liên lạc và lịch sử công việc. Khi bạn hoàn thành, bạn không còn có một ứng dụng trống.

Bây giờ hãy tưởng tượng thay vì trước khi viết bạn phủ nó bằng một tấm giấy bóng kính rõ ràng. Bạn viết tên của bạn. Bạn thêm một tờ giấy bóng kính. Bạn viết thông tin liên lạc của bạn. Giấy bóng kính nhiều hơn. Bạn viết lịch sử công việc của bạn. Khi bạn hoàn thành, bạn vẫn còn ứng dụng trống chưa được xử lý. Bạn cũng có ba tờ giấy bóng kính, mỗi tấm có được hiệu ứng của một thay đổi riêng lẻ.

Cái trước (OOP) bao trùm ý tưởng thay đổi mọi thứ tại chỗ trong khi cái sau (FP) trốn tránh nó. Cả hai đều là mô hình quản lý nhà nước. Cả hai có thể, sử dụng các chiến lược khác nhau, nắm bắt hiệu quả của việc hoàn thành đơn xin việc. OOP thay đổi công cụ bắt đầu trực tiếp, trong khi FP phủ lên những gì xuất hiện trước đó để tạo ra sự thay đổi .


tương tự đẹp, thx !! bạn có phiền (nếu có thể) mở rộng sự tương tự này với những ưu và nhược điểm trong hai cách tiếp cận này.
Rahul Agarwal
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.