Chức năng thuần túy vs nói, đừng hỏi?


14

"Số lượng đối số lý tưởng cho một hàm là 0" là hoàn toàn sai. Số lượng đối số lý tưởng là chính xác số lượng cần thiết để cho phép chức năng của bạn không có hiệu ứng phụ. Ít hơn thế và bạn không cần thiết phải làm cho các chức năng của mình không trong sạch, do đó buộc bạn phải tránh xa hố thành công và leo lên nỗi đau. Đôi khi "chú Bob" được chú ý với lời khuyên của ông. Đôi khi anh ấy sai một cách ngoạn mục. Lời khuyên không đối số của anh ấy là một ví dụ về sau này

( Nguồn: bình luận của @David Arno dưới một câu hỏi khác trên trang web này )

Nhận xét đã đạt được số lượng ngoạn mục 133 lần nâng cấp, đó là lý do tại sao tôi muốn chú ý hơn đến giá trị của nó.

Theo như tôi biết, có hai cách riêng biệt trong lập trình: lập trình chức năng thuần túy (nhận xét này là gì đáng khích lệ) và nói, đừng hỏi (điều này thỉnh thoảng cũng được đề xuất trên trang web này). AFAIK hai nguyên tắc này về cơ bản không tương thích, gần như đối lập với nhau: chức năng thuần túy có thể được tóm tắt là "chỉ trả về giá trị, không có tác dụng phụ" trong khi nói, đừng hỏi có thể tóm tắt là "không trả lại bất cứ điều gì," chỉ có tác dụng phụ ". Ngoài ra, tôi cảm thấy bối rối vì tôi nghĩ rằng, đừng hỏi được coi là cốt lõi của mô hình OO trong khi funcitons thuần túy được coi là cốt lõi của mô hình chức năng - bây giờ tôi thấy các hàm thuần túy được đề xuất trong OO!

Tôi cho rằng các nhà phát triển có thể nên chọn một trong những mô hình này và tuân theo nó? Vâng, tôi phải thừa nhận tôi không bao giờ có thể mang theo mình. Thông thường, nó có vẻ thuận tiện cho tôi để trả lại một giá trị và tôi thực sự không thể thấy làm thế nào tôi có thể đạt được những gì tôi muốn đạt được chỉ với các tác dụng phụ. Thông thường, nó có vẻ thuận tiện đối với tôi khi có tác dụng phụ và tôi thực sự không thể thấy làm thế nào tôi có thể đạt được những gì tôi muốn đạt được chỉ bằng cách trả lại giá trị. Ngoài ra, đôi khi (tôi đoán điều này thật kinh khủng) Tôi có phương pháp làm cả hai.

Tuy nhiên, từ 133 lần nâng cấp này, tôi cho rằng lập trình chức năng thuần túy hiện đang "chiến thắng" vì nó trở thành một sự đồng thuận mà nó vượt trội để nói, đừng hỏi. Điều này có đúng không?

Do đó, trên ví dụ về trò chơi cưỡi mô hình này, tôi đang cố gắng thực hiện : Nếu tôi muốn đưa nó phù hợp với mô hình chức năng thuần túy - LÀM THẾ NÀO?!

Nó có vẻ hợp lý với tôi để có một trạng thái chiến đấu. Vì đây là một trò chơi theo lượt, tôi giữ các trạng thái chiến đấu trong từ điển (nhiều người chơi - có thể có nhiều trận chiến được chơi bởi nhiều người chơi cùng một lúc). Bất cứ khi nào người chơi đến lượt, tôi gọi một phương thức thích hợp ở trạng thái chiến đấu (a) sửa đổi trạng thái cho phù hợp và (b) trả lại các cập nhật cho người chơi, được nối tiếp thành JSON và về cơ bản chỉ cho họ biết những gì vừa xảy ra trên bảng. Điều này, tôi cho rằng, là vi phạm trắng trợn các nguyên tắc CẢ và đồng thời.

OK - Tôi có thể tạo một phương thức TRẢ LẠI trạng thái chiến đấu thay vì sửa đổi nó tại chỗ nếu tôi thực sự muốn. Nhưng! Sau đó tôi có phải sao chép mọi thứ trong trạng thái chiến đấu một cách không cần thiết chỉ để trả lại trạng thái hoàn toàn mới thay vì sửa đổi nó tại chỗ không?

Bây giờ có lẽ nếu di chuyển là một cuộc tấn công, tôi có thể trả lại một nhân vật được cập nhật HP không? Vấn đề là, nó không đơn giản: luật chơi, di chuyển có thể và thường sẽ có nhiều hiệu ứng hơn là chỉ loại bỏ một phần HP của người chơi. Ví dụ: nó có thể tăng khoảng cách giữa các ký tự, áp dụng các hiệu ứng đặc biệt, v.v.

Có vẻ đơn giản hơn nhiều đối với tôi khi chỉ sửa đổi trạng thái tại chỗ và trả lại các cập nhật ...

Nhưng làm thế nào một kỹ sư giàu kinh nghiệm sẽ giải quyết điều này?


9
Theo bất kỳ mô hình nào là một cách chắc chắn để thất bại. Chính sách không bao giờ nên thông minh. Giải pháp cho một vấn đề nên phụ thuộc vào vấn đề chứ không phải niềm tin tôn giáo của bạn về việc giải quyết vấn đề.
John Douma

1
Tôi chưa bao giờ có một câu hỏi được hỏi ở đây về những điều tôi đã nói trước đây. Tôi rất vinh dự. :)
David Arno

Câu trả lời:


14

Giống như hầu hết các câu cách ngôn lập trình, "nói, đừng hỏi" hy sinh sự rõ ràng để đạt được sự ngắn gọn. Hoàn toàn không có ý định đề xuất chống lại việc yêu cầu kết quả tính toán, đó là khuyến nghị không yêu cầu các đầu vào của phép tính. "Đừng nhận, sau đó tính toán, sau đó đặt, nhưng không sao để trả về giá trị từ phép tính", không phải là giá trị.

Nó được sử dụng khá phổ biến đối với mọi người để gọi một getter, thực hiện một số tính toán trên đó, sau đó gọi một setter với kết quả. Đây là một dấu hiệu rõ ràng tính toán của bạn thực sự thuộc về lớp mà bạn gọi là getter trên. "Nói, đừng hỏi" đã được đặt ra để nhắc nhở mọi người cảnh giác với kiểu chống đối đó và nó hoạt động tốt đến mức bây giờ một số người nghĩ rằng phần đó là hiển nhiên và họ tìm kiếm các loại "yêu cầu" khác loại bỏ. Tuy nhiên, cách ngôn chỉ được áp dụng hữu ích cho một tình huống đó.

Các chương trình chức năng thuần túy không bao giờ phải chịu đựng kiểu chống chính xác đó, vì lý do đơn giản là không có setters trong phong cách đó. Tuy nhiên, vấn đề tổng quát hơn (và khó thấy hơn) về việc không trộn lẫn các mức độ trừu tượng ngữ nghĩa khác nhau trong cùng một chức năng áp dụng cho mọi mô hình.


Cảm ơn bạn đã giải thích chính xác "Nói, đừng hỏi".
dùng949300

13

Cả chú Bob và David Arno (tác giả của câu trích dẫn bạn có) đều có những bài học quan trọng mà chúng ta có thể lượm lặt được từ những gì họ viết. Tôi nghĩ rằng nó đáng để học bài học và sau đó ngoại suy những gì thực sự có ý nghĩa cho bạn và dự án của bạn.

Đầu tiên: Bài học của Bác Bob

Chú Bob đang đưa ra quan điểm rằng bạn càng có nhiều đối số trong chức năng / phương thức của mình thì càng có nhiều nhà phát triển sử dụng nó phải hiểu. Tải nhận thức đó không miễn phí và nếu bạn không phù hợp với thứ tự của các đối số, v.v. thì tải nhận thức chỉ tăng.

Đó là một thực tế của con người. Tôi nghĩ rằng lỗi chính trong cuốn sách Clean Code của chú Bob là câu "Số lượng đối số lý tưởng cho một hàm là 0" . Chủ nghĩa tối giản là tuyệt vời cho đến khi nó không. Giống như bạn không bao giờ đạt đến giới hạn của mình trong Giải tích, bạn sẽ không bao giờ đạt được mã "lý tưởng" - bạn cũng không nên.

Như Albert Einstein đã nói, mọi thứ nên đơn giản như nó có thể, nhưng không đơn giản hơn.

Thứ hai: Bài học của David Arno

Cách phát triển David Arno được mô tả là phát triển phong cách chức năng hơn là hướng đối tượng . Tuy nhiên, mã chức năng quy mô cách tốt hơn so với lập trình hướng đối tượng truyền thống. Tại sao? Vì khóa. Bất kỳ trạng thái thời gian nào có thể thay đổi trong một đối tượng, bạn có nguy cơ gặp phải tình trạng chủng tộc hoặc khóa sự tranh chấp.

Đã viết các hệ thống đồng thời cao được sử dụng trong mô phỏng và các ứng dụng phía máy chủ khác, mô hình chức năng hoạt động kỳ diệu. Tôi có thể chứng thực những cải tiến mà phương pháp đã thực hiện. Tuy nhiên, đó là một phong cách phát triển rất khác nhau, với các yêu cầu và thành ngữ khác nhau.

Phát triển là một chuỗi các sự đánh đổi

Bạn biết ứng dụng của bạn tốt hơn bất kỳ ai trong chúng ta. Bạn có thể không cần khả năng mở rộng đi kèm với lập trình kiểu chức năng. Có một thế giới giữa hai lý tưởng được liệt kê ở trên. Những người trong chúng ta đối phó với các hệ thống cần xử lý thông lượng cao và song song lố bịch sẽ có xu hướng hướng tới lý tưởng của lập trình chức năng.

Điều đó nói rằng, bạn có thể sử dụng các đối tượng dữ liệu để giữ tập hợp thông tin bạn cần truyền vào một phương thức. Điều đó giúp giải quyết vấn đề tải nhận thức mà chú Bob đang giải quyết, trong khi vẫn ủng hộ lý tưởng chức năng mà David Arno đang giải quyết.

Tôi đã làm việc trên cả hai hệ thống máy tính để bàn với yêu cầu song song hạn chế và phần mềm mô phỏng thông lượng cao. Họ có những nhu cầu rất khác nhau. Tôi có thể đánh giá cao mã hướng đối tượng được viết tốt được thiết kế xung quanh khái niệm dữ liệu ẩn mà bạn quen thuộc. Nó hoạt động cho một số ứng dụng. Tuy nhiên, nó không hoạt động cho tất cả chúng.

Ai đúng Chà, David đúng hơn chú Bob trong trường hợp này. Tuy nhiên, điểm cơ bản mà tôi muốn nhấn mạnh ở đây là một phương thức nên có nhiều đối số như có ý nghĩa.


Có paralelism. Các trận chiến khác nhau có thể được xử lý song song. Tuy nhiên, có: một trận chiến duy nhất, trong khi nó đang được xử lý, cần phải được khóa.
gaazkam

Vâng, tôi có nghĩa là các độc giả (người gặt hái trong sự tương tự của bạn) sẽ lượm lặt từ các tác phẩm (người gieo giống) của họ. Điều đó nói rằng, tôi đã quay lại để xem xét một số điều tôi đã viết trong quá khứ và đã học lại được điều gì đó hoặc không đồng ý với con người cũ của tôi. Tất cả chúng ta đều học hỏi và phát triển, và đó là lý do số một tại sao bạn nên luôn luôn lý luận thông qua cách thức và nếu bạn áp dụng một cái gì đó bạn đã học.
Berin Loritsch

8

OK - Tôi có thể tạo một phương thức TRẢ LẠI trạng thái chiến đấu thay vì sửa đổi nó tại chỗ nếu tôi thực sự muốn.

Vâng, đó là ý tưởng.

Sau đó tôi có phải sao chép mọi thứ trong trạng thái chiến đấu để trả lại trạng thái hoàn toàn mới thay vì sửa đổi nó tại chỗ không?

Không. "Trạng thái chiến đấu" của bạn có thể được mô hình thành một cấu trúc dữ liệu bất biến, chứa các cấu trúc dữ liệu bất biến khác dưới dạng các khối xây dựng, có thể được lồng trong một số cấu trúc cấu trúc dữ liệu bất biến.

Vì vậy, có thể có những phần của trạng thái chiến đấu không phải thay đổi trong một lượt và những phần khác phải thay đổi. Các phần không thay đổi không phải sao chép, vì chúng không thay đổi, người ta chỉ cần sao chép một tham chiếu đến các phần đó, mà không có bất kỳ rủi ro nào trong việc đưa ra các tác dụng phụ. Điều đó hoạt động tốt nhất trong môi trường ngôn ngữ thu thập rác.

Google cho "Cấu trúc dữ liệu bất biến hiệu quả" và bạn chắc chắn sẽ tìm thấy một số tài liệu tham khảo về cách thức hoạt động nói chung.

Nó có vẻ đơn giản hơn nhiều đối với tôi chỉ cần sửa đổi trạng thái tại chỗ và trả lại các bản cập nhật.

Đối với một số vấn đề nhất định, điều này thực sự có thể đơn giản hơn. Trò chơi và mô phỏng dựa trên vòng có thể thuộc thể loại này, do phần lớn trạng thái trò chơi thay đổi từ vòng này sang vòng khác. Tuy nhiên, nhận thức về những gì thực sự "đơn giản" là ở một mức độ chủ quan nào đó, và nó cũng phụ thuộc rất nhiều vào những gì mọi người đã quen.


8

Là tác giả của bình luận, tôi đoán tôi nên làm rõ nó ở đây, vì tất nhiên có nhiều điều hơn nó so với phiên bản đơn giản hóa mà bình luận của tôi cung cấp.

AFAIK hai nguyên tắc này không tương thích về cơ bản, gần như đối lập với nhau: chức năng thuần túy có thể được tóm tắt là "chỉ trả về giá trị, không có tác dụng phụ" trong khi nói, đừng hỏi có thể tóm tắt là "không trả lại bất cứ điều gì," chỉ có tác dụng phụ ".

Thành thật mà nói, tôi thấy đây là một cách sử dụng thực sự kỳ lạ của thuật ngữ "nói, đừng hỏi". Vì vậy, tôi đã đọc những gì Martin Fowler nói về chủ đề này vài năm trước, đã được khai sáng . Lý do tôi thấy lạ là vì "đừng hỏi" đồng nghĩa với việc tiêm phụ thuộc vào đầu tôi và hình thức tiêm phụ thuộc thuần túy nhất là truyền mọi thứ mà một chức năng cần thông qua các tham số của nó.

Nhưng có vẻ như ý nghĩa mà tôi áp dụng cho "nói đừng hỏi" xuất phát từ việc lấy định nghĩa tập trung vào OO của Fowler và làm cho nó trở nên bất khả tri hơn. Trong quá trình này, tôi tin rằng nó đưa khái niệm vào kết luận logic của nó.

Hãy quay trở lại với sự khởi đầu đơn giản. Chúng tôi có "khối logic" (thủ tục) và chúng tôi có dữ liệu toàn cầu. Thủ tục đọc dữ liệu đó trực tiếp để truy cập nó. Chúng tôi có một kịch bản "hỏi" đơn giản.

Gió về phía trước một chút. Bây giờ chúng ta có các đối tượng và phương thức. Dữ liệu đó không còn cần phải là toàn cầu, nó có thể được truyền qua hàm tạo và được chứa trong đối tượng. Và sau đó chúng ta có các phương thức hành động theo dữ liệu đó. Vì vậy, bây giờ chúng tôi đã "nói, đừng hỏi" như Fowler mô tả. Các đối tượng được nói với dữ liệu của nó. Những phương pháp đó không còn phải yêu cầu phạm vi toàn cầu cho dữ liệu của họ. Nhưng đây là vấn đề: điều này vẫn không đúng "nói, đừng hỏi" theo quan điểm của tôi vì các phương thức đó vẫn phải hỏi phạm vi đối tượng. Đây là nhiều hơn một kịch bản "nói, sau đó hỏi" tôi cảm thấy.

Vì vậy, hãy hướng về thời hiện đại, từ bỏ cách tiếp cận "nó hoàn toàn thất bại" và mượn một số nguyên tắc từ lập trình chức năng. Bây giờ khi một phương thức được gọi, tất cả dữ liệu được cung cấp cho nó thông qua các tham số của nó. Nó có thể (và đã) được lập luận, "vấn đề là gì, điều đó chỉ làm phức tạp mã?" Và đúng vậy, truyền qua các tham số, dữ liệu có thể truy cập qua phạm vi của đối tượng, làm tăng thêm độ phức tạp cho mã. Nhưng việc lưu trữ dữ liệu đó trong một đối tượng, thay vì làm cho nó có thể truy cập được trên toàn cầu, cũng làm tăng thêm sự phức tạp. Tuy nhiên, ít người cho rằng các biến toàn cầu luôn tốt hơn bởi vì chúng đơn giản hơn. Vấn đề là, những lợi ích mà "nói, đừng hỏi" mang lại, vượt xa sự phức tạp của việc giảm phạm vi. Điều này áp dụng nhiều hơn để truyền qua các tham số hơn là giới hạn phạm vi cho đối tượng.private staticvà vượt qua mọi thứ nó cần thông qua các tham số và bây giờ phương thức đó có thể được tin cậy để không lén lút truy cập vào những thứ không nên. Hơn nữa, nó khuyến khích giữ phương thức nhỏ, nếu không, danh sách tham số sẽ vượt quá tầm tay. Và nó khuyến khích các phương pháp viết phù hợp với tiêu chí "hàm thuần túy".

Vì vậy, tôi không thấy "chức năng thuần túy" và "nói, đừng hỏi" trái ngược với nhau. Cái trước là cách thực hiện đầy đủ của cái sau theo như tôi nghĩ. Cách tiếp cận của Fowler chưa hoàn thành "nói, đừng hỏi".

Nhưng điều quan trọng cần nhớ là "thực hiện đầy đủ câu hỏi không hỏi" này thực sự là một lý tưởng, tức là chủ nghĩa thực dụng phải xuất hiện ít hơn chúng ta trở thành duy tâm và do đó coi nó là phương pháp đúng đắn duy nhất từng có. Rất ít ứng dụng có thể thậm chí gần như không có tác dụng phụ 100% vì lý do đơn giản là chúng không có tác dụng gì nếu chúng thực sự không có tác dụng phụ. Chúng tôi cần thay đổi trạng thái, chúng tôi cần IO vv để ứng dụng trở nên hữu ích. Và trong những trường hợp như vậy, các phương pháp phải gây ra tác dụng phụ và vì vậy không thể thuần túy. Nhưng nguyên tắc nhỏ ở đây là giữ cho các phương pháp "không trong sạch" này ở mức tối thiểu; chỉ có chúng có tác dụng phụ bởi vì chúng cần, chứ không phải là tiêu chuẩn.

Nó có vẻ hợp lý với tôi để có một trạng thái chiến đấu. Vì đây là một trò chơi theo lượt, tôi giữ các trạng thái chiến đấu trong từ điển (nhiều người chơi - có thể có nhiều trận chiến được chơi bởi nhiều người chơi cùng một lúc). Bất cứ khi nào người chơi đến lượt, tôi gọi một phương thức thích hợp ở trạng thái chiến đấu (a) sửa đổi trạng thái cho phù hợp và (b) trả lại các cập nhật cho người chơi, được nối tiếp thành JSON và về cơ bản chỉ cho họ biết những gì vừa xảy ra trên bảng.

Có vẻ hợp lý hơn khi có một trạng thái chiến đấu với tôi; nó có vẻ cần thiết Toàn bộ mục đích của mã này là để xử lý các yêu cầu thay đổi trạng thái, quản lý các thay đổi trạng thái đó và báo cáo lại. Bạn có thể xử lý trạng thái đó trên toàn cầu, bạn có thể giữ nó bên trong các đối tượng người chơi riêng lẻ hoặc bạn có thể chuyển nó xung quanh một tập hợp các hàm thuần túy. Cái nào bạn chọn sẽ phù hợp nhất với kịch bản cụ thể của bạn. Nhà nước toàn cầu đơn giản hóa việc thiết kế mã và nhanh chóng, đây là yêu cầu chính của hầu hết các trò chơi. Nhưng nó làm cho cách mã khó hơn để duy trì, kiểm tra và gỡ lỗi. Một tập hợp các hàm thuần túy sẽ làm cho mã phức tạp hơn để thực hiện và có nguy cơ quá chậm do sao chép dữ liệu quá mức. Nhưng nó sẽ đơn giản nhất để kiểm tra và bảo trì. "Cách tiếp cận OO" nằm ở giữa.

Chìa khóa là: không có một giải pháp hoàn hảo nào hoạt động mọi lúc. Mục đích của các chức năng thuần túy là giúp bạn "rơi vào hố thành công". Nhưng nếu cái hố đó quá nông, do sự phức tạp mà nó có thể mang lại cho mã, rằng bạn không rơi vào nó nhiều như một chuyến đi qua nó, thì đó không phải là cách tiếp cận phù hợp với bạn. Nhằm mục đích cho lý tưởng, nhưng hãy thực dụng và dừng lại khi lý tưởng đó không phải là nơi tốt để đi lần này.

Và như một điểm cuối cùng, chỉ cần nhắc lại: các hàm thuần túy và "nói, đừng hỏi" hoàn toàn không đối lập.


5

Đối với bất cứ điều gì, từng nói, tồn tại một bối cảnh, trong đó bạn có thể đặt tuyên bố đó, điều đó sẽ làm cho nó vô lý.

nhập mô tả hình ảnh ở đây

Chú Bob hoàn toàn sai nếu bạn lấy lời khuyên không cần làm đối số. Anh ta hoàn toàn đúng nếu bạn coi điều đó có nghĩa là mọi đối số bổ sung làm cho mã khó đọc hơn. Nó đi kèm với một chi phí. Bạn không thêm đối số vào các hàm vì nó giúp chúng dễ đọc hơn. Bạn thêm đối số vào các hàm vì bạn không thể nghĩ ra một tên hay làm cho sự phụ thuộc vào đối số đó trở nên rõ ràng.

Ví dụ pi()là một chức năng hoàn toàn tốt như nó là. Tại sao? Bởi vì tôi không quan tâm làm thế nào, hoặc thậm chí nếu, nó đã được tính toán. Hoặc nếu nó sử dụng e, hoặc sin (), để đến số mà nó trả về. Tôi ổn với nó vì cái tên cho tôi biết tất cả những gì tôi cần biết.

Tuy nhiên, không phải cái tên nào cũng cho tôi biết tất cả những gì tôi cần biết. Một số tên không tiết lộ quan trọng để hiểu thông tin kiểm soát hành vi của chức năng cũng như các đối số được đưa ra. Đúng vậy, đó là những gì làm cho phong cách chức năng lập trình dễ dàng hơn để lý do.

Tôi có thể giữ mọi thứ không thay đổi và tác dụng phụ miễn phí theo kiểu hoàn toàn OOP. Trả về chỉ đơn giản là một cơ chế được sử dụng để để lại các giá trị trên ngăn xếp cho thủ tục tiếp theo. Bạn có thể duy trì trạng thái bất biến bằng cách sử dụng các cổng đầu ra để truyền đạt các giá trị đến những thứ bất biến khác cho đến khi bạn chạm vào cổng đầu ra cuối cùng mà cuối cùng phải thay đổi thứ gì đó nếu bạn muốn mọi người có thể đọc nó. Điều đó đúng với mọi ngôn ngữ, chức năng hay không.

Vì vậy, đừng cho rằng Lập trình theo chức năng và Lập trình hướng đối tượng là "không tương thích về cơ bản". Tôi có thể sử dụng các đối tượng trong các chương trình chức năng của mình và tôi có thể sử dụng các hàm thuần túy trong các chương trình OO của mình.

Tuy nhiên, có một chi phí để trộn chúng: Kỳ vọng. Bạn có thể trung thành theo các cơ chế của cả hai mô hình và vẫn gây ra nhầm lẫn. Một trong những lợi ích của việc sử dụng ngôn ngữ chức năng là các tác dụng phụ, trong khi chúng phải tồn tại để có được bất kỳ đầu ra nào, được đặt ở một nơi có thể dự đoán được. Tất nhiên trừ khi một đối tượng có thể thay đổi được truy cập một cách vô kỷ luật. Sau đó, những gì bạn đã làm như được đưa ra trong ngôn ngữ đó sụp đổ.

Tương tự, bạn có thể hỗ trợ các đối tượng với các hàm thuần túy, bạn có thể thiết kế các đối tượng không thay đổi. Vấn đề là, nếu bạn không báo hiệu rằng các hàm là thuần túy hoặc các đối tượng là bất biến thì mọi người sẽ không nhận được lợi ích hợp lý nào từ các tính năng đó cho đến khi họ dành nhiều thời gian để đọc mã.

Đây không phải là một vấn đề mới. Trong nhiều năm, mọi người đã mã hóa theo thủ tục trong "ngôn ngữ OO" nghĩ rằng họ đang thực hiện OO vì họ sử dụng "ngôn ngữ OO". Rất ít ngôn ngữ tốt trong việc ngăn bạn bắn vào chân mình. Để những ý tưởng này hoạt động, họ phải sống trong bạn.

Cả hai đều cung cấp các tính năng tốt. Bạn có thể làm cả hai. Nếu bạn đủ can đảm để trộn chúng thì hãy dán nhãn rõ ràng.


0

Đôi khi tôi đấu tranh để có ý nghĩa của tất cả các quy tắc của các mô hình khác nhau. Họ có lúc bất hòa với nhau khi họ ở trong tình huống này.

OOP là một mô hình bắt buộc về việc chạy bằng kéo trong thế giới nơi những điều nguy hiểm xảy ra.

FP là một mô hình chức năng trong đó người ta tìm thấy sự an toàn tuyệt đối trong tính toán thuần túy. Không có gì xảy ra ở đây.

Tuy nhiên, tất cả các chương trình phải kết nối vào thế giới bắt buộc để có ích. Như vậy, lõi chức năng, vỏ mệnh lệnh .

Mọi thứ trở nên khó hiểu khi bạn bắt đầu xác định các đối tượng bất biến (những đối tượng có lệnh trả về một bản sao đã sửa đổi thay vì thực sự biến đổi). Bạn tự nhủ: "Đây là OOP" và "Tôi đang xác định hành vi của đối tượng." Bạn nghĩ lại nguyên tắc Tell, Don't Ask đã thử và đã thử. Rắc rối là, bạn đang áp dụng nó vào vương quốc sai.

Các cảnh giới hoàn toàn khác nhau và tuân theo các quy tắc khác nhau. Vương quốc chức năng xây dựng đến mức nó muốn phát hành các tác dụng phụ vào thế giới. Đối với những hiệu ứng được phát hành, tất cả các dữ liệu sẽ được gói gọn trong một đối tượng bắt buộc (đã được viết theo cách đó!) Cần phải được sử dụng trong vỏ của mệnh lệnh. Nếu không có quyền truy cập vào dữ liệu này, ở một thế giới khác sẽ bị ẩn thông qua việc đóng gói, nó không thể thực hiện được. Đó là tính toán không thể.

Do đó, khi bạn viết các đối tượng bất biến (cái mà Clojure gọi là các cấu trúc dữ liệu liên tục) hãy nhớ rằng bạn đang ở trong miền chức năng. Ném Tell, Đừng hỏi ra ngoài cửa sổ, và chỉ để nó trở lại trong nhà khi bạn vào lại vương quốc bắt buộc.

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.