объем выполненных работ впечатляет (желающих в никуда столько работать, не так много) -> соответственно как тестовое задание, безусловно вы справились успешно.
По поводу улучшений есть множество моментов - но они упираются примерно в одно - избыточность.
например очень большой размер некоторых классов, очень большое количество оберток, черезчур много проверок, много не нужных скобок, оберток и тд.
Вот например у вас множество переменных нулом инициализированы (возможно это такой стандарт в с$, я не сильно знаком)
При этом много где стоят геттеры без проверки на нул, в значения инициализированных нулом. Конечно во многих местах есть эта проверка, и это создает излишнюю избыточность в коде, возможно если бы вы сразу инициировали какими-то значениями по умолчанию (или сделали отложенную инициализацию до того как будет что-то известно про эти переменные), можно было бы избежать и ошибок, и лишних оберток.
Вобщем решение плохо читается - НО повторюсь если это пробный набросок - то это вполне себе хороший вариант, и только с длительным временем из набросков рождаются готовые продукты, качество во многом зависит от уровня вложенных сил, глупо ожидать что в тестовое задание кто-то вложит месяц работы)
Я бы такое точно никому не посоветовал.
П. С.
есть одна тонкость, в том что те кто делают тестовые задания - никогда их не проходят)
У нормальных разработчиков все эти типовые наброски уже в различных вариациях есть, они просто ссылаются на то что у них есть, нормальный разработчик не будет тратить на такое бесполезное занятие время, такое только джуны делают, а джуны как правило не нужны.