Спойлер: эта статья носит собой исключительно развлекательный характер, ничему не учит и тем более не пропагандирует описанный в ней подход.
Разрешите представить вам…
Исключительные исключения
Сегодня мы попытаемся написать что-нибудь простенькое используйся, внимание, ТОЛЬКО исключения. Что имеется в виду?
- Все методы возвращают void
- Все исключения Runtime.
Чтобы уж слишком сильно не загромождать код, условимся, что нам разрешено передавать аргументы в функции обычным способом, без изощрений.
Разрабатывать мы будем простенькую консольную игру. В ней будет выводиться на экран квадратное поле, в одной из клеток которой спрятался таракан. Игроку предлагается за ограниченное число ходов убить таракана, иначе он спрячется и расплодится.
Поехали!
Проектирование
Несмотря на всю абсурдность задачи, мы с вами программисты серьезные, поэтому начнем с проектирования.

Field объединит в себе 2 задачи: хранение состояние поля + его отрисовка. Если вас беспокоит неSOLIDность такого подхода, подумайте над тем, что мы создаем и вам станет легче.

Console будет отвечать за работу с InputStream и OutputStream, с которыми мы его свяжем.

Cockroach будет отвечать за случайно перемещение таракана.
Controller — сердце нашей игры, обрабатывает действия игрока, изменяет состояние поле. Когда заканчиваются ходы, объявляет о проигрыше. Если до этого момента игрок убил таракана — о победе.
Начнем с Console

Тут все предельно просто. Внимание стоит заострить на двух моментах. Во-первых, мы внедряем InputStream и OutputStream через конструктор. Зачем так делать? Затем, чтобы мы получили максимально гибкость. Захотели, чтобы Console печатала или читала из файла? Легко! Кроме того, прослойка между вызывающим кодом и потоками ввода-вывода позволяет нам встраивать промежуточную логику при необходимости. Например, перед выводом каждой строчки добавить «я хочу написать ПСЖ». Ну и второй момент — видите throw new RuntimeException(userInput)??? Разве не прелесть? :)
Field

Класс Field. Обратить тут внимание стоит на 3 момента:
- Вложенный класс Point — удобство наше все.
- Методы draw и drawInit — принимаем Console в духе паттерна Посетитель.
- Все возвращаем исключениями!
Не забудьте прочесть комментарий к классу — в нем указывается, что какой цифрой обозначается. (Для ленивых прокрутить выше — 0 пустая клетка, 1 пробитая игроком, 2 позиция таракана)
Cockroach


Ну не замечательно ли выглядит код? :) Всякий раз, когда нам нужно получить результат вызова функции используем try — catch. Правда тут еще надо и за типами следить…
Обратите внимание, даже методы одного класса возвращают значения через исключения.

Оно даже работает )))
P.S. Полный код можно посмотреть на моем git-е. Также вы можете запустить это нечто и потыкаться в него, исполняемый жабник лежит в корне проекта.