Tôi đã đi đến kết luận rằng CreateDataFile
đang thực hiện một điều bằng cách thực hiện phép đo nhanh và sau đó lưu trữ dữ liệu và thực hiện cả hai trong cùng một phương pháp sẽ trực quan hơn cho người khác sử dụng mã này sau đó phải thực hiện phép đo và ghi vào tệp như các cuộc gọi phương thức riêng biệt.
Tôi nghĩ rằng đây là vấn đề của bạn, thực sự. Phương pháp này không làm một việc. Nó thực hiện hai hoạt động riêng biệt liên quan đến I / O cho các thiết bị khác nhau , cả hai đều hoạt động không tải cho các đối tượng khác:
- Lấy số đo
- Lưu kết quả đó vào một tập tin ở đâu đó
Đây là hai hoạt động I / O khác nhau. Đáng chú ý, cái đầu tiên không làm thay đổi hệ thống tập tin theo bất kỳ cách nào.
Trong thực tế, chúng ta nên lưu ý rằng có một bước giữa ngụ ý:
- Lấy số đo
- Nối tiếp phép đo thành một định dạng đã biết
- Lưu phép đo tuần tự vào một tệp
API của bạn sẽ cung cấp từng loại riêng biệt trong một số hình thức. Làm thế nào để bạn biết một người gọi sẽ không muốn thực hiện một phép đo mà không lưu trữ nó ở bất cứ đâu? Làm thế nào để bạn biết họ sẽ không muốn có được một phép đo từ một nguồn khác? Làm thế nào để bạn biết họ sẽ không muốn lưu trữ nó ở nơi nào khác ngoài thiết bị? Có lý do chính đáng để tách các hoạt động. Tại một trần tối thiểu, mỗi mảnh cá nhân nên có sẵn cho bất kỳ người gọi. Tôi không nên bị buộc phải ghi số đo vào một tệp nếu trường hợp sử dụng của tôi không gọi cho nó.
Ví dụ, bạn có thể tách các hoạt động như thế này.
IMeasurer
có một cách để lấy số đo:
public interface IMeasurer
{
IMeasurement Measure(int someInput);
}
Loại đo lường của bạn có thể chỉ là một cái gì đó đơn giản, như một string
hoặc decimal
. Tôi không khẳng định bạn cần một giao diện hoặc lớp cho nó, nhưng nó làm cho ví dụ ở đây tổng quát hơn.
IFileAccess
có một số phương pháp để lưu tệp:
interface IFileAccess
{
void SaveFile(string fileContents);
}
Sau đó, bạn cần một cách nối tiếp một phép đo. Xây dựng nó vào lớp hoặc giao diện đại diện cho một phép đo hoặc có một phương thức tiện ích:
interface IMeasurement
{
// As part of the type
string Serialize();
}
// Utility method. Makes more sense if the measurement is not a custom type.
public static string SerializeMeasurement(IMeasurement m)
{
return ...
}
Vẫn chưa rõ liệu bạn đã tách hoạt động tuần tự hóa này chưa.
Kiểu phân tách này cải thiện API của bạn. Nó cho phép người gọi quyết định những gì họ cần và khi nào, thay vì buộc các ý tưởng định sẵn của bạn về những gì tôi / O thực hiện. Người gọi nên có quyền kiểm soát để thực hiện bất kỳ hoạt động hợp lệ nào , cho dù bạn nghĩ rằng nó hữu ích hay không.
Khi bạn có các triển khai riêng cho từng thao tác, CreateDataFile
phương thức của bạn sẽ trở thành một tốc ký cho
fileAccess.SaveFile(SerializeMeasurement(measurer.Measure()));
Đáng chú ý, phương pháp của bạn thêm rất ít giá trị sau khi bạn đã thực hiện tất cả điều này. Dòng mã trên không khó để người gọi của bạn sử dụng trực tiếp và phương pháp của bạn hoàn toàn là thuận tiện. Nó nên và là một cái gì đó tùy chọn . Và đó là cách chính xác để API hành xử.
Khi tất cả các phần có liên quan được bao thanh toán và chúng tôi đã thừa nhận rằng phương pháp này chỉ là sự tiện lợi, chúng tôi cần phải viết lại câu hỏi của bạn:
Trường hợp sử dụng phổ biến nhất cho người gọi của bạn là gì?
Nếu toàn bộ vấn đề là làm cho trường hợp sử dụng điển hình của đo và viết vào cùng một bảng thuận tiện hơn một chút, thì sẽ hoàn toàn hợp lý khi chỉ cần cung Board
cấp trực tiếp trên lớp:
public class Board : IMeasurer, IFileAccess
{
// Interface methods...
/// <summary>
/// Convenience method to measure and immediate record measurement in
/// default location.
/// </summary>
public void ReadAndSaveMeasurement()
{
this.SaveFile(SerializeMeasurement(this.Measure()));
}
}
Nếu điều này không cải thiện sự thuận tiện, thì tôi sẽ không bận tâm đến phương pháp này.
Đây là một phương pháp thuận tiện mang đến một câu hỏi khác.
IFileAccess
Giao diện nên biết về loại đo lường và làm thế nào để tuần tự hóa nó? Nếu vậy, bạn có thể thêm một phương thức vào IFileAccess
:
interface IFileAccess
{
void SaveFile(string fileContents);
void SaveMeasurement(IMeasurement m);
}
Bây giờ người gọi chỉ cần làm điều này:
fileAccess.SaveFile(measurer.Measure());
mà chỉ ngắn gọn và có lẽ rõ ràng hơn phương pháp tiện lợi của bạn như được nghĩ trong câu hỏi.