Итак, есть програмка. Хочется сделать ее более красивой.
Код как в изначальном примере, я тут только добавил реакцию на попытку открытия двери.
Выделяем интерфейс для внешнего ввода IInput. Реализация внешнего ввода через консоль.
2. Выделяем интерфейс для внешнего вывода IOutput. Реализация вывода также через консоль.
3. Выделяем класс "Door". Класс зависит от внешних ввода и вывода. Т.е. от интерфейсов IInput, IOutput. Внедрение зависимостей через конструктор.
По сравнению с оригиналом, логика здесь чуть-чуть была причесана.
4. Делаем Program красивым. Program работает с IOutput и Door. Зависимости также задаются через конструктор.
В методе Main инициализируем все сущности, добавляем вызов метода Run у Program.
Измененный файл Program.cs
"Ну и нафига все это надо?" - спросит читатель. - "Столько писанины лишней!".
Не спорю. Но дело в том что теперь:
1. Способы ввода и вывода можно менять, просто добавляя новые реализации (классы) для интерфейсов IInput и IOutput. Например, можно сделать чтение и вывод через файлы, просто создав соответствующие новые классы для этих интерфейсов и проинициализировав их в Program.cs
2. Функционал из IInput и IOutput можно использовать в других частях программы, если такие будут.
3. Наконец, можно покрыть основной код unit тестами.
Пример unit тестов (xUnit).
Используется Moq для подмены реализаций IInput и IOutput.
Классы Program и Door используются "настоящие" и именно их содержимое будет протестировано.
Начало файла ProgramTests.cs
Здесь изображен конструктор для тестов. Он автоматически создает Program с зависимостями перед запуском каждого теста.
Проверяем, что у нас будет на выходе IOutput, если на IInput будут определенные воздействия.
1. Тесты. Если возраст менее или равен 18.
Файл ProgramTests.cs. Часть 2
2. Тесты. Если возраст более 18.
Файл ProgramTests.cs. Часть 3
В принципе, здесь можно еще тестов понаписать. Например, непокрытым остался private метод EnterAge, у класса Door (обработка ошибок парсинга ввода).
Вот такой рефакторинг получился.