Я пришел к выводу, что CreateDataFile
делать одну вещь - сделать быстрое измерение, а затем сохранить данные, и выполнение обоих в одном и том же методе является более интуитивно понятным для кого-то, кто использует этот код, чем для того, чтобы выполнить измерение и записать в файл. как отдельные вызовы методов.
Я думаю, что это ваша проблема, на самом деле. Метод не делает одну вещь. Он выполняет две отдельные операции, связанные с вводом-выводом на разные устройства , которые выгружаются на другие объекты:
- Получить измерение
- Сохранить этот результат в файл где-нибудь
Это две разные операции ввода / вывода. Примечательно, что первый никоим образом не изменяет файловую систему.
На самом деле, мы должны отметить, что есть промежуточный шаг:
- Получить измерение
- Сериализация измерения в известный формат
- Сохраните сериализованное измерение в файл
Ваш API должен предоставлять каждый из них отдельно в некоторой форме. Откуда вы знаете, что вызывающий абонент не захочет проводить измерения, не сохраняя их где-либо? Откуда вы знаете, что они не захотят получить измерение из другого источника? Откуда вы знаете, что они не захотят хранить его где-то кроме устройства? Есть веская причина отделить операции. На голой минимум, каждая отдельная часть должна быть доступна любому абоненту. Я не должен быть принужден записывать измерение в файл, если мой вариант использования не требует его.
Например, вы можете разделить операции следующим образом.
IMeasurer
есть способ получить измерение:
public interface IMeasurer
{
IMeasurement Measure(int someInput);
}
Ваш тип измерения может быть просто чем-то простым, например, string
или decimal
. Я не настаиваю на том, что вам нужен интерфейс или класс для него, но это делает пример здесь более общим.
IFileAccess
есть метод для сохранения файлов:
interface IFileAccess
{
void SaveFile(string fileContents);
}
Тогда вам нужен способ сериализации измерения. Встраивайте это в класс или интерфейс, представляющий измерение, или используйте служебный метод:
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 ...
}
Пока не ясно, выделена ли у вас эта операция сериализации.
Такое разделение улучшает ваш API. Это позволяет вызывающему абоненту решать, что ему нужно и когда, а не заставлять ваши предвзятые представления о том, что выполнять ввод / вывод. Вызывающие должны иметь контроль для выполнения любой действительной операции, независимо от того, считаете ли вы ее полезной или нет.
Если у вас есть отдельные реализации для каждой операции, ваш CreateDataFile
метод становится просто сокращением для
fileAccess.SaveFile(SerializeMeasurement(measurer.Measure()));
Примечательно, что ваш метод добавляет очень мало пользы после того, как вы все это сделали. Вышеуказанная строка кода не является сложной для непосредственного использования вашими абонентами, и ваш метод предназначен исключительно для удобства. Это должно быть и является чем-то необязательным . И это правильный способ поведения API.
После того, как все соответствующие части будут учтены, и мы признаем, что метод просто удобен, нам нужно перефразировать ваш вопрос:
Что будет наиболее распространенным вариантом использования для ваших абонентов?
Если весь смысл состоит в том, чтобы сделать типичный вариант использования измерения и записи на одну и ту же доску немного более удобным, то имеет смысл просто сделать его доступным Board
непосредственно в классе:
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()));
}
}
Если это не улучшит удобство, то я не стал бы беспокоиться о методе вообще.
Этот удобный метод поднимает еще один вопрос.
Должен ли IFileAccess
интерфейс знать о типе измерения и как его сериализовать? Если это так, вы можете добавить метод к IFileAccess
:
interface IFileAccess
{
void SaveFile(string fileContents);
void SaveMeasurement(IMeasurement m);
}
Теперь звонящие просто делают это:
fileAccess.SaveFile(measurer.Measure());
который так же короток и, вероятно, более понятен, чем ваш удобный метод, как задумано в этом вопросе.