Я считаю, что "толстая модель, тонкий контроллер" - это самый подходящий вариант.
Вся логика приложения должна содержаться в моделях. Модель - это не просто сущности из бд, это еще и инкапсулированая логика ее обработки. А контроллер должен говорить модели, что делать и рендерить вьюхи.
Например этот кусок кода неправильный:
class MyController
{
public function myAction()
{
$user = new User();
$user->load($_POST);
if ($user->valiadate()) {
$user->saveToDatabase();
} else {
throw new Exception("...");
}
}
}
Неправильный потому что контроллер знает, как модель сохраняет данные. Что сначала идет валидация, а потом сохранение в бд. И если вы потом решите не проводить валидацию, или добавить еще один проверяющий метод (например), то вам придется делать это везде.
Правильно быдет так: в модели определеить метод, содержащий логику:
class User
{
public static function create(array $data)
{
$record= new static;
$record->load($data);
if($record->validate()){
$record->saveToDatabase();
} else {
throw new Exception("...");
}
return $record;
}
}
А в контроллере просто дергать его и передавать туда данные:
class MyController
{
public function myAction()
{
$user = User::create($_POST);
}
}
Таким образом все логика работы модели (в том числе валидация) инкапсулирована снутри класса, и другие классы не знают, как это происходит.
Такой подход облегчает сопровождение кода а так же облегчает написание тестов.