Я думаю, что схожу с ума, кто-то, заверьте меня.
public class MyFile
{
public static byte[] ReadBinaryFile(string fileName)
{
return File.ReadAllBytes(fileName);
}
public static void WriteBinaryFile(string fileName, byte[] fileContents)
{
File.WriteAllBytes(fileName, fileContents);
}
}
Люди продолжают добавлять код как вышеупомянутое в к нашей кодовой базе, конечно, это неправильно и неприятно, и я делаю миру одолжение путем удаления его и замены всех (или оба в этом случае...) ссылки на него с внутренним кодом.
Есть ли какое-либо реальное выравнивание для такого рода вещи? Я мог пропускать большее изображение? Мы довольно YAGNI-центральны в нашей команде, и это, кажется, бросает вызов этому. Я мог понять, было ли это началом чего-то больше, однако этот код имеет, бездействовал для многих много месяцев, пока я не споткнулся за него сегодня. Чем больше я ищу, тем больше я нахожу.
Как написано, класс/методы - это мусор. Однако я вижу ситуацию, в которой подобный паттерн может быть использован законно:
public interface IFileStorage
{
byte[] ReadBinaryFile(string fileName);
void WriteBinaryFile(string fileName, byte[] fileContents);
}
public class LocalFileStorage : IFileStorage { ... }
public class IsolatedFileStorage : IFileStorage { ... }
public class DatabaseFileStorage : IFileStorage { ... }
Другими словами, если вы хотите поддерживать различные виды хранения, то вы можете обернуть очень простые методы, чтобы реализовать общую абстракцию.
Однако в том виде, в котором он написан, класс не реализует никакого интерфейса, а методы статичны, так что он практически бесполезен. Если вы пытаетесь поддержать вышеупомянутый паттерн, то рефакторите; в противном случае избавьтесь от него.
Если все методы делают, тот же список параметров и передать их, тогда нет, это бессмысленно, и я думаю, что фактически делает код менее понятным. Однако, если метод также передает значения по умолчанию, помимо тех, которые переданы в качестве параметров, или выполняет какую-то общую проверку параметров, то это более сложный аргумент.
Должны ли быть добавлены эти методы-заполнители для последующей логики? Если это так, то следует добавить комментарии или даже ужасное заявление TODO, чтобы кто-то позже завершил мысль.
Это довольно глупо, пока вы не подумаете о том, чтобы скрыть детали реализации этих методов.
Возьмем, к примеру, если у вас был такой код
File.WriteAllBytes(fileName, fileContents);
, разбросанный по всему коду, что, если однажды в будущем вы захотите изменить метод записи файла в вашем приложении? Что ж, в этом случае вам придется пройтись по всему вашему коду и обновить все эти строки кода, чтобы принять новый метод, тогда как, как и в приведенной выше версии, вам нужно будет изменить его только в одном месте.
Я не говорю, что их путь правильный, и вы ошибаетесь, чтобы исправить его, я просто добавляю некоторую перспективу
Существование этих методов - отвратительное отклонение, которое следует немедленно исправить.
Вероятно, они были написаны кем-то, кто не знал о классе File
, а затем переписан кем-то, кто знал, но не был таким смелым, как вы.
Думаю, ответ на этот вопрос зависит от вашей команды, практики и конечного назначения кода (например, найденный вами кусок кода сейчас пишет в файл, но по завершении будет писать в веб-сервис/базу данных/машину морзянки - хотя это "оправдание" как бы отменяется именами классов/методов). Я думаю, вы сами ответили на вопрос: "Мы в нашей команде ориентируемся на YAGNI, и это, кажется, противоречит этому".
Однако окончательным ответом будет спросить того, кто это написал, почему он написал это именно так.
Я не думаю, что эти методы имеют большой смысл как статические методы вспомогательного класса , но в некоторых случаях этот шаблон имеет свои достоинства. Например:
Чтобы отделить код от статического класса . Если MyFile
не был статическим, он мог бы служить абстракцией над статическим объектом IO.File
. Код, который напрямую обращается к файловой системе, может быть очень трудным для тестирования, поэтому подобные абстракции могут быть полезны. (Например, у меня есть интерфейс IFileSystem
, от которого зависит весь мой код ввода-вывода, а мой класс FileSystem
реализует этот интерфейс и обертывает базовые методы для File
].)
Для сохранения согласованных уровней абстракции в методе . Мне не нравится смешивать код в области (например, «клиенты» и «заказы») с кодом в домене _solution) (файлы, байты и биты). Я часто пишу подобные оболочки, чтобы упростить чтение кода и дать мне возможность расширения. Я лучше прочитаю GetDataFileContents ()
, чем File.ReadAllBytes ("foo.dat")
.
Чтобы предоставить контекст . Если фрагмент кода выполняется из-за его побочных эффектов, таких как удаление текстового файла, чтобы выполнить удаление заказа клиента, я бы предпочел прочитать DeleteCustomerOrderFile ("foo.txt")
, чем File.Delete ("foo.txt")
. Первый предоставляет коду контекстную информацию, второй - нет.