Предположим, есть сущность User. Для работы с БД используется слой доступа к данным. Для представления этого User-а логично создать класс User с полями, соответствующими столбцам в таблице БД. Для обмена данными с мобильным приложением используется JSON. Логично создать класс User с полями, которые нужны этому мобильному приложению. Скорей всего часть этих полей будет совпадать с полями для БД, но вряд ли на 100%. Для отрисовки HTML мы во View передаём опять же класс User (предположим, мы не пользуемся новомодными SPA, а пишем по старинке, с отрисовкой на сервере). Опять же эти поля вряд ли на 100% совпадают. При изменении пользователя нам приходит форма. В этой форме опять же поля от класса User. Т.е. это уже 4-я сущность. А ещё разные REST-методы и формы могут требовать разный набор полей. Как со всем этим поступать?
1. Использовать первый класс везде. Возникает опасность, что юзер сможет изменить поле, которое ему менять не положено. С этим можно пытаться бороться...
2. Писать новый класс для каждого юз-кейса. Как их называть? Ведь очевидно, что в части классов придётся работать с несколькими классами User сразу и можно просто запутаться, кто есть кто. Например в Java, где импорты переименовывать нельзя, а полностью специфицированные имена слишком длинны. Делать префиксы? Ну их не хватит на всё. Как данные копировать из одного такого класса в другой? Рефлексией? Руками скучно и долго.
3. Не писать классы, а использовать Map<String, Object>. Ну это уже динамическая типизация получается со всеми её минусами.