Берем базовый "абстрактный" класс, где геттер возвращает экземпляр объекта дефолтного поведения, который является NullObject, ссылка на который хранится в "холдере", а "сверху" геттер переопределен и возвращает ссылку на экземпляр конкретного объекта поведения. И 99% логики лежит в базовом классе, вот и подумайте теперь, что нужно использовать.
Или есть у вас базовая команда, у которой есть геттер isValid, который по дефолту возвращает _isValid, значение которого false, зачем _isValid не спрашивайте, тут много отговорок(IDE сгенерировал, "ну как же, есть геттер - значит нужен холдер" и т.д.), а каждый наследник переопределяет этот геттер и на основании чего-то выдает значение, а еще и геттеры-lazy, значение которых необходимо рассчивать при каждом обращении
и т.д. и т.д.
@Wolsh, а если все внутренние расчеты будут использовать методы/свойства, которые могут быть переопределены, тогда они все по идее вернут все в рублях и проблем не будет, но вот если будет использован, какой-то переопределенный метод, который может вернуть что-то в рублях, но вот вместо геттера, будет использован его холдер(который почему-то все хранит в долларах) - вот тут-то и будет ошибка. Я таких примеров за свою практику встречал сотни