2009-02-25 25 views
6

Tôi đã mulling về một post bởi Misko Hevery rằng phương pháp tĩnh trong Java là một cái chết để testability. Tôi không muốn thảo luận về vấn đề kiểm thử mà là về khái niệm phương pháp tĩnh. Tại sao mọi người ghét nó quá nhiều?phương pháp tĩnh làm cho Java một ngôn ngữ chức năng giả?

Đúng là chúng tôi không có bao đóng (nhưng chúng tôi có chức năng ẩn danh hơi khó xử), lambdas & hoạt động như đối tượng lớp học đầu tiên. Theo một cách nào đó, tôi nghĩ rằng các phương thức tĩnh có thể được sử dụng để bắt chước các hàm như là các đối tượng lớp đầu tiên.

+1

Tôi nghĩ bạn đang bối rối về chức năng với thủ tục. Một lỗi phổ biến. –

+0

Java không có chức năng ẩn danh, bạn có thể nghĩ đến các lớp ẩn danh. Trong thực tế Java không có chức năng ở tất cả ... chỉ có phương pháp ;-) –

Trả lời

2

Một đặc điểm của lập trình chức năng là tính bất biến của dữ liệu. static ngụ ý rằng bạn không cần một đối tượng (ví dụ) đại diện cho nhà nước, vì vậy đó không phải là một khởi đầu tồi. Tuy nhiên, bạn có trạng thái ở cấp lớp, nhưng bạn có thể thực hiện điều này final. Vì các phương thức (tĩnh) không phải là các hàm hạng nhất, bạn sẽ vẫn cần các công trình xấu xí như các lớp ẩn danh để tiếp cận một kiểu nhất định của lập trình hàm trong Java.

FP được thực hiện tốt nhất bằng ngôn ngữ chức năng vì ngôn ngữ cần thiết hỗ trợ cho những thứ như chức năng bậc cao hơn, bất biến, tính minh bạch tham chiếu, v.v.

Tuy nhiên, điều này không có nghĩa là bạn không thể lập trình theo kiểu chức năng bằng ngôn ngữ bắt buộc như Java. Các ví dụ khác cũng có thể được đưa ra. Nó không phải vì bạn đang lập trình trong Java mà bạn đang làm OOP. Bạn có thể lập trình với dữ liệu toàn cầu và luồng điều khiển không có cấu trúc (goto) bằng ngôn ngữ có cấu trúc như C++. Tôi có thể làm OOP trong một ngôn ngữ chức năng như Scheme. Vv

Steve McConnell đề cập đến sự khác biệt của chương trình trong một ngôn ngữ lập trình so với vào một ngôn ngữ trong Code Complete (cũng là một tài liệu tham khảo rất phổ biến trên SO).

Vì vậy, trong ngắn hạn, nếu bạn nói rằng "phương pháp tĩnh bắt chước chức năng hạng nhất", tôi không đồng ý.

Nếu, tuy nhiên, và tôi nghĩ rằng đây là điểm bạn muốn vượt qua, bạn sẽ nói rằng "các phương pháp tĩnh có thể giúp lập trình theo kiểu chức năng trong Java", tôi đồng ý.

4

Phương pháp tĩnh thực hiện kiểm tra khó khăn vì chúng không thể thay thế được, đơn giản như vậy.

Làm cách nào để các phương thức tĩnh "bắt chước" các hàm làm đối tượng lớp đầu tiên ? Có thể cho rằng chúng tệ hơn bất cứ thứ gì khác trên mặt trận này. Bạn có thể "bắt chước" các hàm như các đối tượng lớp đầu tiên bằng cách tạo các giao diện đơn phương thức, và thực sự các Bộ sưu tập Java của Google thực hiện chính xác điều này ở một số vị trí (cho các vị từ, các dự báo, vv). Điều đó không thể được thực hiện với các phương thức tĩnh - không có cách nào (ngoài việc phản ánh) để truyền khái niệm "khi bạn muốn áp dụng một hàm, hãy sử dụng phương thức này.

Không, tôi không thể thấy Chúng không khuyến khích nhà nước thay đổi (vì trạng thái duy nhất có sẵn là trạng thái toàn cầu và bất kỳ trạng thái có thể thay đổi nào được truyền qua thông số) nhưng chúng không giúp ích cho các chức năng như là các đối tượng lớp đầu tiên ”

C# có tốt hơn hỗ trợ cho điều này (với biểu thức lambda và đại biểu) nhưng thậm chí đó không phải là chung chung như nó có thể. (So sánh nó với F #, ví dụ.)

phương pháp

Tính đến Java 8, phương pháp tài liệu tham khảo sẽ cho phép được chuyển đổi với các trường hợp giao diện đơn phương pháp thích hợp, mà sẽ làm tất cả điều này hơn có liên quan. Trở lại năm 2009 đó là một chặng đường dài mặc dù ...

+0

Tại sao bạn muốn thay thế một phương pháp để thử nghiệm? Tôi muốn thử nghiệm phương pháp không phải là sự thay thế! – ThomasD

+1

Điều gì sẽ xảy ra nếu phương pháp truy cập vào máy chủ web trên đối diện hemishpere và bạn không thực sự muốn điều đó, vì bạn nên sử dụng dữ liệu giả tĩnh hơn. –

+1

+1 nhận xét của Anton. Nếu bạn không thể thay thế các phụ thuộc của mình, các bài kiểm tra "unit" của bạn sẽ kiểm tra những phụ thuộc đó cũng như phương thức mà họ đang thực sự cố gắng thử nghiệm. –

0

Phản đối lớn nhất của tôi đối với phương pháp tĩnh là chúng không đa hình và chúng không được sử dụng theo cách hướng đối tượng, thay vào đó bạn có lớp học (không phải là một đối tượng) để truy cập chúng.

3

Chức năng! = Chức năng, và đối với hồ sơ, tôi sẽ yêu cầu một phương pháp! = Function ...

Java là một kiểu gõ ngôn ngữ hướng đối tượng tĩnh. Java cũng đã duy trì độ tinh khiết tương đối theo cách đó nhưng không có nơi nào gần một ngôn ngữ chức năng.

Mặc dù đúng là bạn có thể bắt chước hành vi lập trình chức năng với lập trình bắt buộc bạn sẽ không bao giờ có được cú pháp gọn gàng mà bạn muốn có để tính toán lambda. Theo một cách nào đó, nếu ngôn ngữ không hỗ trợ phép tính lambda đúng thì đó không phải là ngôn ngữ lập trình hàm.

C++ có chức năng, nhưng C++ cũng có các lớp. C++ do đó có hai loại hàm, hàm thành viên và hàm. Khi bạn nói phương pháp bạn có nghĩa là một chức năng thành viên. Bởi vì phương thức được gọi trên một thể hiện của một đối tượng. Nhưng khi bạn nói phương pháp tĩnh, bạn có nghĩa là chỉ có chức năng (trong ý nghĩa C/C++). Đây chỉ là một từ vựng để đề cập đến các yếu tố của mã của bạn. Và trong mã Java không thể tồn tại bên ngoài một lớp, một phương thức sẽ ngụ ý rằng nó thuộc về một số loại lớp nào đó.

Cho đến nay không có gì trong những gì tôi đã nói liên quan đến lập trình chức năng nhưng tôi nghĩ rằng bạn nhận được điểm mà bạn sai.

Tôi khuyên bạn nên xem các ngôn ngữ lập trình hàm thuần túy như Haskell hoặc Erlang. Bởi vì ngôn ngữ lập trình chức năng thường không có closers.

Yêu cầu của bạn là các phương thức tĩnh có thể được sử dụng để bắt chước các hàm như đối tượng lớp đầu tiên có vẻ kỳ quái với tôi. Nghe có vẻ giống một ngôn ngữ lập trình động hơn là lập trình hàm.

0

Nếu bạn chỉ sử dụng các phương pháp tĩnh thì bạn đang lập trình theo kiểu thủ tục, không hướng đối tượng.

Tuy nhiên, bối cảnh duy nhất tôi có thể nghĩ về việc điều này sẽ ổn ở đâu trong các bài học lập trình đầu tiên trước khi định hướng đối tượng được giới thiệu.

0

Trong Java, bạn không thể cung cấp hàm làm đối số cho hàm khác.

Trong một ngôn ngữ chức năng, nếu bạn có một hàm

def addOne(i) = i + 1 

bạn có thể vượt qua đó để một chức năng mà ví dụ như áp dụng nó cho tất cả các yếu tố của một danh sách.

Trong Java, với

public static int addOne(int i) { return i + 1; } 

không có cách nào để làm điều đó.

Các vấn đề liên quan