Мне кажется, не все варианты.
А если философия в том, что можно совершенно по разному построить приложение?
ИМХО без философии хорошего проекта не бывает, другое дело что идеи использования бывают разными.
Я выбрал второй вариант, так как перегиб в сторону первого(Он должен содержать инструменты...) может сделать фреймворк слишком абстрактным и не применимым для конкретных задач. А перегиб в сторону третьего(Должен навязывать философию использования...) варианта сделает фреймворк слишком негибким. Лучшее - враг хорошего.
А мне кажется 3 вариант имеет ввиду не жесткость и негибкость, а то что определенное действие может быть выполнено только одним способом.
И при этом не ограничивается каличество самих действий (чтобы можно было сделать все что угодно). Философия должна помогать понимать код стороннему рабработчику и не плодить велосипеды.
Но в критических ситуациях должна быть возможность смело плюнуть на философию.
2 вариант.
Навязывать философию разработки, но предоставлять выбор для реализации.
Всегда должна оставаться гибкость в этапах разработки.
Как пример можно привести управляемый/не управляемый код в C#.
Новичку фреймворк не нужен. Новичок сам должен написать один-два-много фреймворков, чтобы разобраться в принципах, получить опыт и понять, что не следует изобретать велосипеды.
А опытному разработчику нужен фреймворк, который достаточно мощен, чтобы решать разные задачи, гибок, чтобы решать нестандартные задачи, подробен, чтобы избавить от рутины и изобретения велосипедов, и нравится, чтобы с ним приятно было работать.
Не стоит забывать, что каждой задаче - свой инструмент.
Третий вариант - однозначно полезен в крупных проектах и больших командах.
Первый (первые два - чем они отличаются) - на нестандартных задачах, в руках умелых программистов...
Третий вариант полезен, если хорошо подходит проекту, если все накладные расходы (резервирования памяти, обращения к базам и т.п.) оказываются затребованы и оправданы.
Первые два - если фреймворк надо задействовать частично, раздёргать на компоненты и модули, выбросить всё лишнее.
И наконец, третий вариант хорош, если надо быстро включиться в работу и некогда экспериментировать и выбирать, что будет, если сделать так, а не иначе.
Использую Tapestry для построения веб-части. Устраивает компонентный подход, довольно логичное построение контроллеров, отделение представление от контроллера. Для бизнес-уровня (в терминах J2EE) использую Spring. Устраивает удобный IoC-контейнер, набор фабрик для подключения Hibernate, обработки транзакций, интерцептирования и т.д. Тем более что Spring нативно подключается к Tapestry.
Каков должен быть, на Ваш взгляд, хороший framework?