Вы сами разрабатываете фреймворк? Если нет, ваш вопрос не применим, потому что вы должны выбрать из уже существующих фреймворков и их существующих решений. В этом случае ваш вопрос должен быть переформулирован так: «Как мне выполнить модульное тестирование / внедрение зависимостей в Framework X».
Если вы сами разрабатываете фреймворк, вам следует сначала проверить, как уже существующие подходы к этому вопросу. И вы должны также разработать свои собственные требования, а затем просто пойти с самым простым решением. Без требований ваш вопрос чисто эстетический и аргументированный.
Imho самое простое решение состоит в том, чтобы иметь общедоступные свойства, которые инициализируются значениями по умолчанию, предоставленными вашей платформой, в противном случае вы можете вставить свои макеты здесь. (Это равносильно вашему решению для получения / установки, но без упомянутого раздувания. Вам не всегда нужны средства получения и установки.) При желании, если вам это действительно нужно, вы можете предоставить конструктор для инициализации их в одном вызове (как вы предложили) .
Синглтоны - элегантное решение, но, опять же, вы должны спросить себя, применимо ли это в вашем случае? Если в вашем приложении должны быть разные экземпляры одного и того же типа объекта, вы не можете использовать его (например, если вы хотите издеваться над классом только в половине вашего приложения).
Конечно, действительно здорово иметь все варианты. У вас могут быть getters / setter, конструкторы, и когда инициализация опущена, значения по умолчанию берутся из одноэлементной фабрики. Но иметь слишком много опций, когда они не нужны, не удивительно, это вызывает беспокойство, так как программист должен выяснить, какое соглашение, опцию и шаблон использовать. Я определенно не хочу принимать десятки проектных решений только для того, чтобы запустить простой CRUD.
Если вы посмотрите на другие рамки, то увидите, что серебряной пули нет. Часто одна структура использует различные методы в зависимости от контекста. В контроллерах DI - действительно простая вещь, посмотрите на $ helpers, переменные $ components CakePHP, которые инструктируют вводить соответствующие переменные в класс контроллера. Для самого приложения синглтон по-прежнему хорош, так как всегда есть только одно приложение. Свойства, которые реже изменяются / высмеиваются, вводятся с использованием общедоступных свойств.
В случае MVC подклассирование также является вполне приемлемым вариантом: точно так же, как AppController, AppView, AppModel в CakePHP. Они вставляются в иерархию классов между фреймворками и всеми вашими классами Controller, View и Model. Таким образом, вы можете объявить глобальные переменные для вашего основного типа классов.
В Java из-за динамических загрузчиков классов и рефлексии у вас есть гораздо больше возможностей для выбора. Но, с другой стороны, вам необходимо поддерживать гораздо больше требований: параллельные запросы, общие объекты и состояния между рабочими потоками, серверами распределенных приложений и т. Д.
Вы можете ответить на вопрос, что подходит именно вам, если вы знаете, что вам нужно в первую очередь. Но на самом деле, зачем вы пишете просто еще один новый фреймворк?