Tôi có chức năng API này:
public ResultEnum DoSomeAction(string a, string b, DateTime c, OtherEnum d,
string e, string f, out Guid code)
Tôi không thích nó. Bởi vì thứ tự tham số trở nên quan trọng không cần thiết. Nó trở nên khó khăn hơn để thêm các lĩnh vực mới. Thật khó để nhìn thấy những gì đang được thông qua. Việc tái cấu trúc phương thức thành các phần nhỏ hơn khó hơn vì nó tạo ra một chi phí khác để chuyển tất cả các tham số trong các hàm phụ. Mã khó đọc hơn.
Tôi đã đưa ra một ý tưởng rõ ràng nhất: có một đối tượng đóng gói dữ liệu và truyền nó đi thay vì truyền từng tham số một. Đây là những gì tôi đã đưa ra:
public class DoSomeActionParameters
{
public string A;
public string B;
public DateTime C;
public OtherEnum D;
public string E;
public string F;
}
Điều đó đã giảm khai báo API của tôi xuống:
public ResultEnum DoSomeAction(DoSomeActionParameters parameters, out Guid code)
Đẹp. Trông rất ngây thơ nhưng chúng tôi thực sự đã giới thiệu một sự thay đổi lớn: chúng tôi đã giới thiệu tính đột biến. Bởi vì những gì chúng ta trước đây đã làm là thực sự để vượt qua một đối tượng bất biến ẩn danh: tham số hàm trên stack. Bây giờ chúng tôi đã tạo ra một lớp mới rất dễ thay đổi. Chúng tôi tạo ra khả năng thao túng trạng thái của người gọi . Đó là hút. Bây giờ tôi muốn đối tượng của mình bất biến, tôi phải làm gì?
public class DoSomeActionParameters
{
public string A { get; private set; }
public string B { get; private set; }
public DateTime C { get; private set; }
public OtherEnum D { get; private set; }
public string E { get; private set; }
public string F { get; private set; }
public DoSomeActionParameters(string a, string b, DateTime c, OtherEnum d,
string e, string f)
{
this.A = a;
this.B = b;
// ... tears erased the text here
}
}
Như bạn thấy tôi thực sự đã tạo lại vấn đề ban đầu của mình: quá nhiều tham số. Rõ ràng đó không phải là con đường để đi. Tôi sẽ làm gì đây? Tùy chọn cuối cùng để đạt được sự bất biến như vậy là sử dụng cấu trúc "chỉ đọc" như thế này:
public struct DoSomeActionParameters
{
public readonly string A;
public readonly string B;
public readonly DateTime C;
public readonly OtherEnum D;
public readonly string E;
public readonly string F;
}
Điều đó cho phép chúng tôi tránh các nhà xây dựng có quá nhiều tham số và đạt được sự bất biến. Trên thực tế, nó sửa tất cả các vấn đề (thứ tự tham số vv). Chưa:
- Mọi người (bao gồm FXCop & Jon Skeet) đồng ý rằng việc phơi bày các lĩnh vực công cộng là xấu .
- Eric Lippert et al nói rằng dựa vào các trường chỉ đọc cho sự bất biến là một lời nói dối .
Đó là khi tôi bối rối và quyết định viết câu hỏi này: Cách đơn giản nhất trong C # để tránh vấn đề "quá nhiều tham số" mà không đưa ra khả năng biến đổi? Có thể sử dụng cấu trúc chỉ đọc cho mục đích đó mà không có thiết kế API xấu?
XÁC NHẬN:
- Hãy cho rằng không có vi phạm nguyên tắc responsibiltiy duy nhất. Trong trường hợp ban đầu của tôi, hàm chỉ ghi các tham số đã cho vào một bản ghi DB.
- Tôi không tìm kiếm một giải pháp cụ thể cho chức năng đã cho. Tôi đang tìm kiếm một cách tiếp cận tổng quát cho các vấn đề như vậy. Tôi đặc biệt quan tâm đến việc giải quyết vấn đề "quá nhiều tham số" mà không đưa ra khả năng biến đổi hoặc thiết kế khủng.
CẬP NHẬT
Các câu trả lời được cung cấp ở đây có những lợi thế / bất lợi khác nhau. Vì vậy, tôi muốn chuyển đổi nó thành wiki cộng đồng. Tôi nghĩ rằng mỗi câu trả lời với mẫu mã và Ưu / Nhược điểm sẽ tạo ra một hướng dẫn tốt cho các vấn đề tương tự trong tương lai. Bây giờ tôi đang cố gắng tìm hiểu làm thế nào để làm điều đó.
DoSomeActionParameters
là một đối tượng vứt đi, sẽ bị loại bỏ sau khi gọi phương thức.