Như đã nêu trong tiêu đề, các tham số tùy chọn, chẳng hạn như các tham số được sử dụng trong C # có hữu ích hay chúng là một trở ngại cho việc bảo trì ứng dụng và nên tránh vì chúng có thể làm cho mã khó hiểu hơn?
Như đã nêu trong tiêu đề, các tham số tùy chọn, chẳng hạn như các tham số được sử dụng trong C # có hữu ích hay chúng là một trở ngại cho việc bảo trì ứng dụng và nên tránh vì chúng có thể làm cho mã khó hiểu hơn?
Câu trả lời:
Theo kinh nghiệm của tôi, các tham số tùy chọn là một điều tốt. Tôi chưa bao giờ thấy chúng khó hiểu (ít nhất là không khó hiểu hơn hàm thực tế), vì tôi luôn có thể nhận được các giá trị mặc định và biết những gì được gọi.
Một lần sử dụng cho chúng là khi tôi phải thêm một tham số khác vào một chức năng đã được sử dụng chung, hoặc ít nhất là trong giao diện công cộng. Không có chúng, tôi phải làm lại chức năng ban đầu để gọi một đối số có một đối số khác và điều đó có thể trở nên thực sự cũ nếu tôi kết thúc việc thêm các đối số nhiều lần.
new Circle(size, color, filled, ellipseProportions)
ở đâu size
và color
được yêu cầu và phần còn lại là mặc định.
Nói chung, nếu bạn cần nhiều tham số / tùy chọn thường xuyên, các chức năng của bạn đang hoạt động quá nhiều và nên bị phá vỡ. Bạn có khả năng phá vỡ SRP (Nguyên tắc trách nhiệm duy nhất).
Tìm các tham số có thể được nhóm lại, ví dụ (x và y, trở thành một điểm).
Là những cờ tham số tùy chọn với một mặc định? Nếu bạn đang sử dụng cờ, chức năng sẽ được tách ra.
Điều đó không có nghĩa là bạn không bao giờ nên có các tham số tùy chọn, nhưng nói chung, nhiều hơn một hoặc hai tham số gợi ý mùi mã.
Nó cũng có thể là một đầu mối rằng hàm, thực sự phải là một lớp, với các tham số tùy chọn được thay đổi thành các thuộc tính và một phần tham số bắt buộc của hàm tạo.
Thông số tùy chọn là tốt
Thông thường, lời biện minh là a) bạn biết rằng bạn có rất nhiều đối số có thể có cho phương thức của mình nhưng bạn không muốn quá tải vì sợ làm mờ API của mình hoặc b) khi bạn không biết tất cả các đối số có thể nhưng bạn không muốn buộc người dùng của bạn cung cấp một mảng. Trong mỗi trường hợp, các tham số tùy chọn đến cứu hộ một cách gọn gàng và thanh lịch.
Dưới đây là một số ví dụ:
1. Bạn muốn tránh quá tải và không muốn chỉ định một mảng
Hãy xem printf () từ C, Perl, Java, v.v ... Đó là một ví dụ tuyệt vời về sức mạnh của các tham số tùy chọn.
Ví dụ:
printf("I want %d %s %s",1,"chocolate","biccies");
printf("I want %d banana",1);
Không quá tải, không có mảng, đơn giản và trực quan (một khi bạn đã nắm được các mã định dạng chuỗi tiêu chuẩn). Một số IDE thậm chí sẽ cho bạn biết nếu chuỗi định dạng của bạn không khớp với các tham số tùy chọn của bạn.
2. Bạn muốn cho phép sử dụng mặc định và giữ chúng ẩn khỏi người dùng phương thức
sendEmail ("test@example.org");
Phương thức sendEmail phát hiện ra rằng các giá trị thiết yếu khác nhau bị thiếu và điền vào chúng bằng cách sử dụng các giá trị mặc định đã xác định (chủ đề, cơ thể, cc, bcc, v.v.). API được giữ sạch sẽ, nhưng linh hoạt.
Một lưu ý về quá nhiều thông số
Tuy nhiên, như những người khác đã tuyên bố, việc có quá nhiều tham số bắt buộc đối với một phương thức cho thấy rằng bạn có thể có điều gì đó không đúng với thiết kế của bạn. Điều này đặc biệt đúng nếu chúng chia sẻ cùng loại vì chúng có thể được nhà phát triển chuyển đổi một cách tình cờ dẫn đến kết quả lạ khi chạy:
String myMethod(String x, String y, String z, String a, int b, String c, int d) {}
là một ứng cử viên lý tưởng cho việc tái cấu trúc Đối tượng tham số giới thiệu để tạo
String myMethod(ParameterObject po) {}
class ParameterObject {
// Left as public for clarity
public String x;
public String y;
... etc
}
Điều này đến lượt nó có thể dẫn đến một thiết kế tốt hơn dựa trên mẫu Factory với đặc tả được cung cấp làm đối tượng tham số.
Một trong những vấn đề với các tham số mặc định trong C # (Tôi đang nghĩ void DoS Something (int x = 1)) là chúng là hằng số. Điều đó có nghĩa là nếu bạn thay đổi mặc định, bạn sẽ phải biên dịch lại bất kỳ người tiêu dùng nào của cuộc gọi phương thức đó. Trong khi điều này là đủ dễ dàng để làm, có những lúc điều này là nguy hiểm.
Nó phụ thuộc vào những gì mã của bạn đang làm. Nếu có mặc định hợp lý thì bạn nên sử dụng các tham số tùy chọn nhưng nếu không có mặc định hợp lý thì việc thêm tham số tùy chọn sẽ làm cho mã của bạn phức tạp hơn. Trong nhiều trường hợp, các tham số tùy chọn là một cách gọn gàng để kiểm tra nil và cắt bỏ logic phân nhánh. Javascript không có các tham số tùy chọn nhưng có một cách để mô phỏng chúng với | | (logic hoặc) và tôi sử dụng nó mọi lúc khi thực hiện các công việc liên quan đến cơ sở dữ liệu vì nếu người dùng không cung cấp một số giá trị thì tôi thay thế các giá trị của riêng tôi bằng sự trợ giúp của || Điều này giúp tôi tiết kiệm được những rắc rối khi viết cả đống câu lệnh if.
Các tham số tùy chọn là một cách tuyệt vời để làm cho những điều đơn giản trở nên đơn giản và những điều phức tạp có thể xảy ra đồng thời. Nếu có một mặc định hợp lý rõ ràng mà hầu hết người dùng sẽ muốn, ít nhất là trong các trường hợp sử dụng nhanh và bẩn, thì họ không cần phải viết bản tóm tắt để chỉ định thủ công mỗi khi họ gọi hàm của bạn. Mặt khác, nếu mọi người có thể có lý do chính đáng để muốn thay đổi nó, thì nó cần phải được phơi bày.
Sử dụng một lớp học là IMHO một giải pháp khủng khiếp, vì nó dài dòng, không hiệu quả và không phù hợp với mô hình tinh thần điển hình của những gì một lớp học làm. Một chức năng là sự trừu tượng hoàn hảo cho một động từ, tức là làm một cái gì đó và trở lại. Một lớp là sự trừu tượng đúng cho một danh từ, tức là một cái gì đó có trạng thái và có thể được thao tác theo nhiều cách. Nếu trước đây phải là mô hình tinh thần của người dùng API, thì đừng biến nó thành một lớp.
Vấn đề với các đối số tùy chọn là mọi người có xu hướng chỉ đưa vào ngày càng nhiều (và nhiều hơn) đối số cho hàm thay vì trích xuất mã có liên quan vào một hàm mới. Điều này được đưa đến cực đoan trong php . Ví dụ:
bool array_multisort ( array &$arr [, mixed $arg = SORT_ASC
[, mixed $arg = SORT_REGULAR [, mixed $... ]]] )
Các tham số tùy chọn về cơ bản là một cách khác nhau để nạp chồng một hàm. Vì vậy, điều này về cơ bản đi xuống: "quá tải một chức năng xấu"?
Ban đầu tôi rất thích tính năng này trong python và đã sử dụng nó để 'mở rộng' các phương thức đã sử dụng. Và nó trông đẹp và dễ dàng, nhưng nó sẽ sớm quay lại; bởi vì khi tôi thêm một tham số tùy chọn, điều này đã sửa đổi hành vi của một phương thức hiện có mà máy khách cũ dựa vào và theo cách không bị bắt bởi các trường hợp kiểm thử đơn vị hiện có. Về cơ bản làm điều này là phá vỡ Nguyên tắc Đóng mở; mã được mở để mở rộng nhưng đóng để sửa đổi. Vì vậy, tôi tin rằng việc sử dụng tính năng này để sửa đổi mã hiện tại không phải là một ý tưởng tốt; nhưng không sao nếu được sử dụng từ đầu
Tôi nghĩ sẽ tốt hơn khi quá tải một hàm với các chữ ký khác nhau (tức là các tham số) hơn là sử dụng các tham số tùy chọn.