Почему контроллеры запускаются первыми в ASP.NET MVC? - PullRequest
1 голос
/ 27 августа 2011

Я хочу улучшить текущую реализацию ASP.NET MVC Framework.Текущий код:

routes.MapRoute(null, "I-want-to-fly", new { controller = "Airport", action = "Fly" });

public class AirportModel 
{
   public List<Plane> Planes { get; private set; }
   public List<Pilot> Pilots { get; private set; }

   public void AddFly(Plane plane, Pilot pilot, Passenger passenger)
   {
        // . . .
   }
}

public class AirportController
{
   private AirportModel model;

   [HttpGet]
   public ViewResult Fly(string from, string to)
   {
       var planes = return (from p in model.Planes 
                            where p.CityFrom == from && p.CityTo == to
                            select p).ToList();
       return View(planes);
   }

   [HttpPost]
   public ActionResult Fly(Plane plane, Passenger passenger, DateTime time)
   {
       if (!(ModelState.IsValid && plane.TimeOfDeparture == time))
            return View();

       var pilot = (from p in model.Pilots 
                    where p.Free && p.CanAviate(plane.Id) 
                    select p).First();
       model.AddFly(plane, pilot, passenger);

       return RedirectToAction("Succeed");
   }
}

Мое предложение:

routes.MapRoute(null, "I-want-to-fly", new { model = "Airport", action = "Fly" });

public class AirportModel 
{
    private List<Plane> planes;
    private List<Pilot> pilots;

    private void AddFly(Plane plane, Pilot pilot, Passenger passenger)
    {
        // . . .
    }

    [HttpGet]
    public ViewResult Fly(string from, string to)
    {
        var planes = return (from p in model.Planes 
                             where p.CityFrom == from && p.CityTo == to
                             select p).ToList();
        return View(suitablePlanes);
    }

    [HttpPost]
    public ActionResult Fly(Plane plane, Passenger passenger, DateTime time)
    {
        if (!(ModelState.IsValid && new PlaneController().CanFly(plane, time)))
                return View();

        var pilot = (from p in pilots 
                     where p.Free && p.CanAviate(plane.Id) 
                     select p).First();
        AddFly(plane, pilot, passenger);

        return RedirectToAction("Succeed");
    }
}

public static class PlaneController
{
    public static bool CanFly(Plane plane, DateTime time)
    {
        return plane.TimeOfDeparture == time; // it will be more complex
    }
}

Видите ли, таким образом, нам не нужно чрезмерное количество контроллеров и их методов.Модель создаст контроллер только по производительности: в основном для проверки ввода пользователя (без проверки ввода, проверки бизнеса) .

Как вы думаете, может ли эта идея иметь продолжение?Или что с ним не так?

Спасибо за ваши ответы!

ОБНОВЛЕНИЕ: Я заметил, что нам нужно заменить реализации контроллера и посмотреть в результатеизменение состояния модели (в основном).Итак, если модель вызывает изменение реализации, почему модель не может сделать это?

ОБНОВЛЕНИЕ 2: Мне кажется, я объяснил неправильно.Я не хочу, чтобы модель делала всю работу, конечно нет!Я пытаюсь сказать, что не контроллер должен решить, что делать с моделью и какой вид наиболее подходит для этого пользовательского запроса.

Разве не странно, что модель не знает, как визуализировать себя, но какой-то контроллер знает?

Не странно, чем нам нужен контроллер для запроса GET, гденет ничего для контроля?

Я пытаюсь удалить эти странности.

ОБНОВЛЕНИЕ 3: Я понимаю, что это нигде не может быть применено.Главный вопрос: может ли он улучшить некоторую часть современных реализаций MVC?В основном меня интересует ASP.NET MVC - можем ли мы

  1. удалить избыточные контроллеры или некоторые его методы
  2. работать напрямую с моделями

, используяэта идея?Возможно ли и в чем проблемы этой идеи?

Найдены проблемы:

  1. Более сильная связь между моделью и видом / контроллером - но в настоящее время яне думаю, что это проблема.Фактически это показывает, что представления и контроллеры были созданы в справке для основного элемента - модели.

ОБНОВЛЕНИЕ 4: Я изменил код, показывая «до / после».Может быть, этот пример будет лучше.

Ответы [ 4 ]

8 голосов
/ 27 августа 2011

Разве это не противоречит самой идее MVC ?Ваша модель отделена от вашего контроллера и вашего взгляда.Таким образом (как вы предлагаете) вы не сможете заменить вашу модель другой реализацией или контроллером в этом отношении.

updated I:

Вы, конечно, можете позволитьМодель также выполняет роль контроллера, но с этого момента вы больше не говорите о шаблоне проектирования MVC.Для MVC модель делает и не должна теперь о представлении.Это работа контроллеров.

Контроллер получает пользовательский ввод и инициирует ответ, вызывая объекты модели.Контроллер принимает входные данные от пользователя и инструктирует модель и область просмотра выполнять действия на основе этого ввода.

В шаблоне MVC Модель не просто привязана к вашей модели базы данных, это может бытьсочетание вашей модели базы данных и шаблона хранилища, где вы реализуете свою бизнес-логику.

Самая большая проблема, с которой я сталкиваюсь в вашем предложении, заключается в том, что он делает код одноразовым.Я получаю модель, которая тесно связана с ее представлениями, которые мне действительно не нужны, если я хочу использовать модель любым другим способом, каким захочу.


Обновление II

  • Я думаю, что вас вводит в заблуждение фактическое слово «Контроллер», я некоторое время думал об этом, и ваш последний комментарий вроде бы подтверждает этодля меня

    Контроллеры - это некоторые объекты, которые проверяют соответствие пользовательского ввода бизнес-логике.

    Контроллеры воздействуют на пользовательский ввод, они могут проверять пользовательский ввод, но ихответственность за проверку действительности прекращается там.Бизнес-логика входит в модель (опять же, модель, как определено шаблоном MVC, а не модель, как в модели данных).Их основная цель - решить, какой вид отобразить.

  • Также из одного из ваших последних комментариев:

    Как вы думаете, если [asp.net mvc] будет развиваться по-моему, будет ли эторешить проблему избыточных контроллеров?

    Asp.Net MVC следует схеме проектирования MVC.Ваше предложение нет.Это больше похоже на паттерн ModelControlled View, просто для обозначения имени.Также нет резервированных контроллеров, с контроллерами проблем нет, они являются неотъемлемой частью решения.

И попытка упрощенно пояснить, что я имею в виду с помощью примера кода:

namespace DataProject.Model
{
    public class AirportModel 
    {
        public List<Plane> Planes { get; set; }
        public List<Pilot> Pilots { get; set; }
        public List<Passenger> Passengers { get; set; }
        public List<Flight> Flights { get; set; }
    }

}

namespace SomeProject.Repository
{
    public class AirportRepository
    {
        private DataProject.Model.AirportModel model;

        //constructor sets the model somehow

        public bool AddFlight(Plane plane, List<Passenger> passengers, DateTime time)
        {
            //Business logic
            if (plane.TimeOfDeparture != time) return false;

            var pilot = (from p in model.Pilots 
                         where p.Free && 
                               p.CanAviate(plane.Id) 
                         select p).FirstOrDefault();
            //More Business logic
            if (pilot == null) return false;

            //Add plane, pilot and passenger to database
            model.Flights.add(new Flight{Pilot = pilot, Plane = plane, Passengers = passengers});
            //Even here you could decide to do some error handling, since you could get errors from database restrictions
            model.Save(); 

            return true;    
        }

        public List<Planes> GetPlanes(string from, string to)
        {
            return (from p in model.Planes 
                        where p.CityFrom == from && p.CityTo == to
                        select p).ToList();
        }
    }
}

namespace MVCApp.Controllers
{
    public class AirportController
    {
        private SomeProject.Repository.AirportRepository repository;

        [HttpGet]
        public ViewResult Fly(string from, string to)
        {
            var viewModel = repository.GetPlanes(from, to);
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Fly(Plane plane, List<Passenger> passengers, DateTime time)
        {
            if (!ModelState.IsValid) return View(); 

            if (!repository.AddFlight(plane, pilot, passenger)) return View();

           return RedirectToAction("Succeed");
        }
    }
}
3 голосов
/ 28 августа 2011

Без обид, но как именно это улучшение?

Итак, вы создали класс под названием PersonModel, который на самом деле вообще не выполняет "моделирование вещей" - это работа, которую выполняют контроллерыdo - у вас есть обработка, получение и публикация и вызов для отображения Views, а затем у вас есть статический «Контроллер», который действительно ничего не контролирует и имеет отношение к бизнес-логике.Честно говоря, я не понимаю, как это улучшение.

Конкретным примером является то, что у вас есть контроллер, проверяющий, является ли Age >= 18, что является очень «бизнес-правилом» для контроллера.Это не цель контроллера.Это задача модельного объекта - заниматься такими вещами, как бизнес-логика.Контроллеры, , как выразился один человек , - это скорее электронный куратор.В вашем примере вы передали его чему-то гораздо меньшему, чем куратор.

Существуют различные роли, которые объекты играют в приложении MVC.Представления показывают нам вещи и предоставляют нам способы взаимодействия с приложением.Контроллеры обрабатывают входные данные из представления и обслуживают необходимые представления.Модели предоставляют место для размещения данных, а также логики и бизнес-правил, которые охватывает модель.Сервисы обрабатывают такие вещи, как сохранение данных в каком-то хранилище, например, в БД.

1 голос
/ 28 августа 2011

Вы программист, тогда вы можете согласиться или не согласиться с шаблоном MVC. Но шаблон, который вы описали, не поддерживает разделение интересов и разрушает всю идею о MVC

Это не имеет ничего общего с MVC.

Это 'MVNothing'

:) Шучу * _ ^

1 голос
/ 27 августа 2011

Вы можете делать все в одном классе вообще без контроллеров, но вам нужна «отдельная проблема». Таким образом, контроллер отвечает за запрос http и проверку, а модель отвечает только за данные.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...