2010-04-20 20 views
10

Trong hầu hết các ngôn ngữ hướng đối tượng khác. nó sẽ là sacrilege để có mỗi chức năng nhận được một mảng kết hợp của các đối tượng hơn là liệt kê từng chữ ký trong phương thức. Tại sao, liệu nó có được chấp nhận và thường được sử dụng trong hầu hết các khuôn khổ phổ biến cho cả hai ngôn ngữ này để làm điều này?Tại sao các mảng cấu hình có thể chấp nhận các tham số trong PHP và Javascript?

Có biện minh nào ngoài mong muốn có chữ ký súc tích không?

Tôi thấy lợi ích trong điều này - rằng API có thể không thay đổi khi các thông số tùy chọn mới được thêm vào. Nhưng Javascript và PHP đã cho phép các tham số tùy chọn trong chữ ký phương thức của chúng. Nếu bất cứ điều gì, có vẻ như Java hoặc một ngôn ngữ OO khác sẽ được hưởng lợi từ điều này nhiều hơn ... nhưng tôi hiếm khi thấy mô hình này ở đó.

Điều gì mang lại?

Trả lời

2

Lý do chính là các ngôn ngữ cụ thể đó chỉ đơn giản là không hỗ trợ có nhiều quy ước gọi điện cho cùng một tên hàm. I E. bạn không thể làm như sau:

public function someFunc(SomeClass $some); 
public function someFunc(AnotherClass $another); 
public function someFunc(SomeClass $some, AnotherClass $another); 

Vì vậy, bạn phải tìm một cách khác để tạo ra những cách đơn giản để vượt qua các biến của bạn xung quanh, trong PHP chúng ta kết thúc với someFunc(array('some'=>$some, 'another'=>$another)) vì nó là cách thuận tiện mà thôi. Trong JavaScript, chúng tôi sẽ sử dụng các đối tượng, không phải là xấu: someFunc({some: something, another: anotherthing})

10

Theo ý kiến ​​của tôi, rất nhiều chức năng này đang tăng số lượng đối số mà họ chấp nhận, trên 10 không phải là không phổ biến. Ngay cả khi bạn thực hiện các tham số tùy chọn, bạn vẫn phải gửi chúng theo thứ tự.

Xem xét một chức năng như:

function myFunc(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13){ 
    //... 
} 

Giả sử bạn muốn sử dụng đối số 3 và 11 chỉ. Dưới đây là mã của bạn:

myFunc(null, null, null, 'hello', null, null, null, null, null, null, null, 'world'); 

bạn sẽ không thay chỉ:

myFunc({ 
    a3 : 'hello', 
    a11 : 'world' 
}); 

?

1

Đầu tiên của tất cả các kỹ thuật như vậy là rất đơn giản cho các lập trình viên.

Chúng không cần phải nhớ thứ tự của tất cả các thông số của tất cả các chức năng trong ứng dụng của bạn. Mã trở nên dễ đọc hơn và mạnh mẽ hơn.

Bất kỳ sự phát triển, cải tiến hoặc tái cấu trúc nào trong tương lai sẽ không khó cung cấp. Mã trở nên dễ bảo trì hơn.

Nhưng có một số cạm bẫy. Ví dụ, không phải mọi IDE sẽ cung cấp cho bạn một mã đơn giản hoàn thành với các hàm như vậy và các tham số của chúng.

4

Có một vài lý do cho việc này.

Đầu tiên là không phải tất cả các danh sách đối số đều có thứ tự tự nhiên. Nếu có một trường hợp sử dụng để chỉ cung cấp đối số thứ nhất và thứ 6, bây giờ bạn phải điền vào bốn trình giữ chỗ mặc định. Jage minh họa điều này tốt. Thứ hai là nó rất khó để nhớ thứ tự các đối số phải xảy ra in Nếu bạn lấy một loạt các số như đối số của bạn, nó không có khả năng biết số nào có nghĩa là gì. Hãy lấy ví dụ imagecopyresampled($dest, $src, 0, 10, 0, 20, 100, 50, 30, 80). Trong trường hợp này, mảng cấu hình hoạt động như các đối số được đặt tên của Python.

0

Theo tôi có 2 lý do tại sao điều này đã phát triển:

  1. Array Avatar của rất dễ dàng để tạo và thao tác, ngay cả với các loại hỗn hợp.
  2. Các lập trình viên PHP/JS thường có nền tảng không học thuật và ít được truyền tải từ các ngôn ngữ như Java và C++.
2

của Ruby sau phương pháp này là tốt, và thậm chí đã nghĩ ra một cú pháp ngắn gọn hơn có nghĩa đặc biệt cho sử dụng băm như initializers, như của Ruby 1.9:

# old syntax 
myFunc(:user => 'john', :password => 'password'); 

# new syntax 
myFunc(user: 'john', password: 'password'); 

Vấn đề được giải quyết là, trong những ngôn ngữ, bạn không thể quá tải các chức năng dựa trên loại đối số. Điều này dẫn đến các lớp phức tạp với một hàm tạo duy nhất có thể có một danh sách đối số khổng lồ và khó sử dụng. Việc sử dụng các đối tượng kiểu băm để cung cấp các tham số cho phép một loại quá tải giả theo tên tham số chứ không phải theo loại.

chỉ vấn đề thực sự của tôi với thông lệ này là nó trở nên khó khăn để ghi lại lập luận của bạn: PHPDoc for variable-length arrays of arguments

2

Một trong những lý do quan trọng nhất tại sao bạn không thấy điều này trong ngôn ngữ OO khác là bạn có lẽ đề cập đến các ngôn ngữ được biên dịch như C++ hoặc Java.

Trình biên dịch có trách nhiệm xác định, tại thời gian biên dịch không thực hiện, phương thức bạn muốn gọi và điều này thường được thực hiện dựa trên chữ ký, vì vậy về cơ bản nó phải được thực hiện theo cách này. Đây cũng là cách quá tải phương thức được thực hiện bằng các ngôn ngữ này.

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