Интерфейсы нужны для возможности замены реализации не затрагивая основной код. При использовании интерфейсов основной код ничего не знает об деталях реализации (слабая связанность). Соответственно, реализацию можно вынести в отдельный модуль (изолировать сложность). Если основной код ссылается непосредственно на класс, содержащий реализацию (сильная связанность), то сложность программы возрастает и сопровождение программы усложняется. Поэтому интерфейсы особенно нужны на границах подсистем.
Если реализация отделена от основного кода, то становится легко подменить её в тестах, например, подсунуть in memory реализацию, вместо БД. См. fake object (не путать с mock). Это еще один важный плюс интерфейсов.
Возможно, в простых программах интерфейсы не слишком нужны. Но, поскольку вы говорите об учебном примере, то использовать их (приучая сразу к хорошему, правильному стилю) - это правильно.