Jeśli MVC to „Separation of Concerns”, to dlaczego wprowadzono składnię Razor?

22

Moje pytanie dotyczy wzorca projektowego MVC i Razor Syntax wprowadzonych przez Microsoft.

Podczas nauki wzorca projektowania MVC powiedziano mi, że pomysł opiera się na zasadzie znanej jako Separation of Concerns .

Ale Razor Składnia pozwala nam używać C # w Wyświetleń bezpośrednio.

Czy to nie jest skrzyżowanie obaw?

John Strowsky
źródło
7
Warto wspomnieć, że ASP.NET MVC tak naprawdę nie implementuje wzorca projektowego MVC. MVC dyktuje, że model jest obserwowany przez widok zmian, co oczywiście nie ma miejsca w ASP.NET MVC.
Benjamin Gruenbaum
11
Może to również pomóc, jeśli zmienisz sposób myślenia o widokach. Widoki nie są kodem po stronie klienta. Są to szablony po stronie serwera, które po przetworzeniu generują HTML po stronie klienta. A jako kod po stronie serwera, jest całkowicie akceptowalny, że jest tam kod C #.
Eric King
6
@EricKing z wyjątkiem części, w której systemy szablonów, które pozwalają na dowolny kod, zawsze prowadzą, poprzez ścieżkę najmniejszego oporu, do złego projektu, strasznego naruszenia warstw i niemożności utrzymania. Niestety wydaje się, że jest to lekcja, której każda społeczność musi nauczyć się sama.
hobbs
12
@ Hobbs Wow, ok. Nie z mojego doświadczenia. Z pewnością nie zawsze i (oczywiście) programiści ponoszą odpowiedzialność zawodową. Nie obwiniam tego narzędzia.
Eric King
7
@BenjaminGruenbaum Czy w dzisiejszych czasach każdy „MVC” nie jest inny w zarządzaniu współzależnościami? Do tego stopnia, że ​​mówienie o Jedynym i prawdziwym stylu MVC nie jest już produktywne, ale bardziej pragmatyczne byłoby używanie tego terminu w przypadku dowolnego systemu, który rozsądnie dzieli odpowiedzialność na Modele , Widoki i Kontrolery, jednak są one współzależne?
Alex

Odpowiedzi:

66

Łączymy składnię Razor z rozdzieleniem obaw.

Oddzielne obawy związane są ze strukturą kodu.

Możliwość używania C # w widokach nie przeszkadza. Nie ma to nic wspólnego z oddzieleniem obaw jako takich.

Jasne, możesz ustrukturyzować kod w swoim widoku, aby nie był zgodny z separacją problemów, ale co z kodem C # używanym tylko do wyświetlania? Gdzie by to mieszkało?

Oded
źródło
1
Ale C # jest językiem po stronie serwera?
John Strowsky
6
@John - więc? Jeśli chcesz sformatować daty do wyświetlania (a wyświetlanie oznacza zawsze po stronie klienta), gdzie je sformatujesz? Model? Kontroler? Ani. Zrobiłbyś to w widoku.
Oded
16
@John - więc twoja data jest przechowywana w DB, przekazujesz ją przez model / kontroler do twojego widoku. Potrzebujesz tam w HTML, więc wyślesz go jakoś do formatu JS, zamiast formatować bezpośrednio w C #? Czemu? Dlaczego to jest lepsze? A raczej, w jaki sposób takie podejście jest bardziej oddzieleniem obaw?
Oded
25
@ NPSF3000 - język nie jest „po stronie serwera” ani „po stronie klienta”. Jest to separacja architektoniczna - i prawdopodobnie jedna z implementacji językowych (JavaScript jest językiem po stronie serwera lub klienta - pamiętaj node.js).
Oded
14
@FreeAsInBeer - jest to logika, która należy do klienta - ktoś we Francji chciałby, aby daty (i waluta / liczby) były sformatowane inaczej niż w Stanach Zjednoczonych. Klient najlepiej wiedziałby, jak powinny być wyświetlane. Jest to logika prezentacji i jako taka należy do widoku.
Oded
35

Zamiast bezpośrednio odpowiadać na pytanie, moja odpowiedź kwestionuje założenia przyjęte w pytaniu. To znaczy założenie, że Razor został zbudowany dla MVC, jest błędne. Pracuję w Microsoft w zespole ASP.NET i mam o tym wiedzę z pierwszej ręki.

Razor nie zaczął się jako silnik podglądu dla MVC. Został stworzony dla stron internetowych ASP.NET , które są prawdopodobnie tak daleko, jak to tylko możliwe, w stronę najmniej podzielonego obszaru zainteresowań spektrum. Został stworzony jako nowoczesna alternatywa dla ASP.NET Web Forms / Classic ASP i oczywiście wielu innych podobnych platform programistycznych dla serwerów. Ideą Razora było stworzenie niemal płynnych przejść między HTML (znacznikami) a C # (kodami).

Dopiero później zespół (w tym ja) zdecydował, że składnia Razor będzie miała sens ze względu na silnik widoku dla MVC, który został napisany przez ten sam zespół.

Jeśli chodzi o to, czy Razor umożliwia, utrudnia, ulepsza lub zmienia koncepcję separacji problemów w ASP.NET MVC, odpowiedź Odeda jest natychmiastowa.

Eilon
źródło
2
Tak, głosuj bez komentarza. Poprawiłem swoją odpowiedź, aby wyjaśnić, że kwestionuję założenie zawarte w pierwotnym pytaniu. Moim zdaniem na pytanie nie można odpowiedzieć bezpośrednio, ponieważ ma ono błędną przesłankę.
Eilon
Z ciekawości, czy w ASP MVC rozważano inne silniki szablonów?
NWard
2
@NWard W tym czasie istniało wiele zewnętrznych silników widoków dla ASP.NET MVC, ale nie rozważaliśmy ich zbyt mocno. Uznaliśmy, że Razor jest łatwiejszy do zrozumienia (HTML to HTML, C # to C #), a także lepiej zżelował z projektem ASP.NET Web Pages.
Eilon
1
@Alex och, z pewnością nie mogę przypisać sobie uznania za Razor, ale doceniam twój komentarz!
Eilon
1
@ateri Po krótkiej chwili jest to duża liczba w lewym górnym rogu odpowiedzi.
Mark Hurd
9

Mylicie „rozdzielenie technologii” z „rozdzieleniem obaw”. Podstawową ideą części „Widok” MVC jest to, że kod w „Widoku” nie wykonuje bezpośrednio żadnego dostępu do danych lub logiki, a pozostawia się to odpowiednio częściom „Model” i „Kontroler”. „Kontroler” przekształca dane, wykonuje niezbędną logikę i kieruje je do właściwego „Widoku”. Widok może także przeprowadzać transformacje danych, ale staram się zachować je czysto kosmetyczne, takie jak wspomniana powyżej transformacja daty.

whoisthemachine
źródło
wydaje się, że nie oferuje to nic istotnego w porównaniu z punktami przedstawionymi i wyjaśnionymi we wcześniejszych odpowiedziach, szczególnie tym
komara
4
+1 Formułowane w zwięzły i jasny sposób, z innym wyjaśnieniem niż poprzednie odpowiedzi.
Alex
@gnat Chciałem tylko wyjaśnić, gdzie leży jego zamieszanie, a następnie szybko wyjaśnić, w jaki sposób zasada separacji obaw dotyczy wzorca projektowego MVC. Być może powinienem był poświęcić więcej czasu na to, co oznacza „rozdzielenie obaw”?
whoisthemachine
0

Mogę wymyślić idealny Don't do itprzykład.

Powiedzmy, że mamy kontroler produktu:

public class ProductController()
{
    public ViewResult Discontinued()
    {
        var db = new ProductsDb();
        var products = db.Products.Where(x => x.Discontinued).ToList();
        return new ViewResult(products);
    }
}

Z brzytwą mamy alternatywę

public class ProductController()
{
    public ViewResult Discontinued()
    {
        var db = new ProductsDb();
        var products = db.Products.ToList();
        return new ViewResult(products);
    }
}

i naszym zdaniem:

@model IEnumerable<Product> 

@foreach (var item in Model.Where(x => x.Discontinued)) {
    ....
}

Myślę, że to całkiem oczywiste, że drugie rozwiązanie wydaje się tak błędne. Jeśli robisz coś takiego, nie obwiniaj brzytwy - obwiniaj siebie.

I nie zapomnij: Możliwość używania C # w widokach nie jest funkcją brzytwa, było to również możliwe w widokach ASP.NET. Dzięki maszynce do golenia jest to trochę prostsze.

Jeśli szukasz silnika szablonów, który ma więcej szyn, powinieneś spojrzeć na nancy.fx dzięki silnikowi Super simple view.

Jürgen Steinblock
źródło