Cada um no seu quadrado no ASP.NET MVC

Como nos 2 últimos posts eu falei sobre dúvidas que eu tinha recebido, vou continuar na mesma linha, só que agora busquei a dúvida nesta thread do grupo .NetArchitects, entre outras (muitas) coisas que foram discutidas foi levantado a dúvida sobre a responsabilidade da View,  na dúvida o Emmanuel propõe um cenário que está exposto abaixo:

Se você tem que exibir transações de conta corrente, por exemplo, débito e crédito, mas quando o saldo fica negativo você quer colocar a linha em vermelho, é uma regra de apresentação. Mas onde estaria esse código? Acho que não estaria no domínio por que não diz respeito a ele... Seria no Controller?

Esta é uma pergunta mais comum do que se imagina, já me perguntaram diversas vezes sobre a responsabilidade de cada letra do MVC, e é por isso que eu coloquei como título deste post como “Cada um no seu quadrado”.

A resposta simples e direta para a pergunta acima é que essa regra fica na View, mas vamos elaborar um pouco mais, por que não no Controller? Simples, por que assim ele estaria invadindo o quadrado da View, vou exemplificar o meu ponto de vista:

No cenário proposto pelo Emmanuel, o Controller enviaria os dados através da ViewData para a View e ela por sua vez verificaria se o Saldo é negativo, caso fosse exibiria ele em vermelho, vamos ver um pouco de código.

Vamos começar pelo modelo, para representar o cenário criei 3 classes, a Conta que contem os dados da conta e as transações, a Transação que representa cada transação da conta e o Repositório que para o exemplo irá preencher os objetos com dados randômicos.

Conta

public class Conta
{
    public int Numero { get; set; }
    public int Agencia { get; set; }
    public IList<Transacao> Transacoes { get; set; }
    public double Saldo { get; set; }
}

Transação

public class Transacao
{
    public DateTime Data { get; set; }
    public string Descricao { get; set; }
    public double Valor { get; set; }
}

Repositório

public class ContaRepositorio
{
    public Conta get(int Agencia, int Numero) {
        //aqui faria a consulta no banco, vou fazer um
        //faz de conta para facilitar
        Conta conta = new Conta();
        conta.Agencia = Agencia;
        conta.Numero = Numero;
        conta.Transacoes = new List<Transacao>();
        Random rnd = new Random();
        for (int i = 0; i < 15; i++)
        {
            conta.Transacoes.Add(new Transacao{Data = DateTime.Now.AddDays(-i),Descricao = "Transação nº "+i, Valor= rnd.Next(0,358)});
        }
        conta.Saldo = rnd.Next(-1245, 1245);
        return conta;
    }
}

Vamos ver agora o Controller, criei uma única action que mandará através da ViewData os dados da Conta, neste ponto é que surge a dúvida, posso colocar a inteligência de trocar a cor aqui? Bom, tecnicamente pode, poderia criar um objeto intermediário que tem sido chamado de ViewModel para armazenar esta “condição”, mas na minha opinião o Controller estará invadindo o quadrado da View. Na soluçao proposta abaixo eu passo somente os dados para a View.

Controller

public class ContaController : Controller
{
    //
    // GET: /Conta/

    public ActionResult Index()
    {
        ContaRepositorio rep = new ContaRepositorio();
        ViewData.Model = rep.get(1234, 123456);
        return View();
    }

}

Vamos agora para a View, de acordo com o valor do saldo é escolhido a classe que será aplicano na tag que contém o saldo.

View

<h2>Extato de Conta</h2>

<fieldset>
    <p>Numero: <%= Html.Encode(Model.Numero) %></p>
    <p>Agencia: <%= Html.Encode(Model.Agencia) %></p>
    <table>
        <thead>
            <tr>
                <th>Data</th>
                <th>Descrição</th>
                <th>Valor</th>
            </tr>
        </thead>
        <tbody>
            <%foreach (var item in Model.Transacoes){%>
            <tr>
                <td><%= Html.Encode(String.Format("{0:d/M/yyyy}", item.Data))%></td>
                <td><%= Html.Encode( item.Descricao)%></td>
                <td><%= Html.Encode(String.Format("{0:F}", item.Valor)) %></td>
            </tr>

            <%} %>
        </tbody>
    </table>
    <%
    string classe;
    if (Model.Saldo < 0)
    {
        classe = "negativo";
    }
    else {
        classe = "positivo";
    } %>
    <p>Saldo: <span class="<%=classe%>"><%= Html.Encode(String.Format("{0:F}", Model.Saldo)) %></span></p>
</fieldset>

No CSS adicionei as seguintes classes:

.positivo{color:Blue;}
.negativo{color:Red;}

O resultado esta na imagem abaixo:

image

Este código eu fiz com a intenção de demonstrar que a View não é burra (no bom sentido), ela pode e deve conter regras que são de interface, como no exemplo acima.

O Emmanuel quis complicar um pouco mais o cenário e colocou o seguinte:

E se esse núcleo do meu sistema é consumido por diversas interfaces? Mobile, desktop, web; essa regra da interface, não deveria estar em outro local que não a interface?

Quando tive os primeiros contatos com o ASP.NET MVC tive a mesma dúvida, mas com o tempo e várias pesquisas fiquei convencido que isto não é possível e nem interessante, digo isso por 2 motivos:

  1. O primeiro é técnico, como o MVC é um padrão de Interface Gráfica ele depende muito do ambiente, que neste caso é o ASP.NET MVC, ou seja, eu não conseguiria reutilizar o Controller do ASP.NET MVC para uma aplicação Windows Form ou uma aplicação Mobile.
  2. O segundo é sobre os diferente tipos de mídias que poderíamos utilizar para a nossa interface, cada uma dessas mídias tem suas próprias preocupações de acessibilidade e usabilidade e para lidar com essas preocupações cada uma delas deve ter autonomia.

O código deste exemplo já está disponível.

Bom, espero ter respondido a dúvida do Emmanuel e de outras pessoas. Até a próxima.


Comments

Pedro Reys
Pedro Reys
8 February 2010 00:09
Victor, concordo com o seu ponto de vista no post. A única alteração que eu faria era criar um Html Helper para lidar com o saldo. Digo isso pois costumo seguir a regra do Rob Conery: <a href="blog.wekeroad.com/.../">"If there's an IF, make a Helper"</a>
Emmanuel Brandão
Emmanuel Brandão
8 February 2010 00:16
Respondeu! Obrigado por compartilhar a sua experiência de MVC com a gente.
pingback
mrtweet.com
8 February 2010 07:32
Pingback from mrtweet.com

Most Tweeted Articles by Windows7 Experts
Rodrigo Vieira
Rodrigo Vieira
8 February 2010 08:38
Um dos aspectos mais interessantes do ASP.NET MVC é ter trazido à tona esse tipo de discussão, ou seja, por ser uma arquitetura muito limpa e elegante, os desenvolvedores trabalhando com MVC acabam também procurando limpar e repensar sua forma de programar. Nos tempos do webforms me parecia que tudo era permitido, não fazia diferenca se tal regra estaria aqui ou ali.
victor
victor
8 February 2010 15:48
@Pedro Reis, fiquei em dúvida em fazer ou não, mas decidi não fazer pela simplicidade do exemplo, se eu tivesse alguma coisa mais complexa que não fosse a escolha da classe css eu faria um Helper.
victor
victor
8 February 2010 15:59
@Rodrigo Vieira, este é o ponto que eu mais gosto do MVC, ele coloca cada um no seu quadrado (hehe), várias pessoas que até então não se preocupavam com arquitetura começaram a se preocupar por causa deste framework.
Rafael Noronha
Rafael Noronha
10 February 2010 07:30
Reconhecer o fato do MVC fazer parte da camada de apresentação é muito importante.

Outra discussão interessante neste caminho é o papel do Model dentro de uma arquitetura mais abrangente - se ele se limita à camada de apresentação ou se faz parte de um Domain Model. Que tal agendar um post sobre sua experiência em relação a isto? Smile
victor
victor
10 February 2010 08:24
@Rafael Noronha, essa realmente é uma discução interessante, existe muita confusão quando se fala do Model do MVC, vou começar a escrever sobre o assunto. Obrigado. Smile
Andrew Baxter
Andrew Baxter
18 February 2010 09:49
Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog. I am sure my visitors will find that very useful.
stocks
stocks
18 February 2010 18:22
Yes, I have been looking for this all week better late than never!
online stock trading
online stock trading
20 February 2010 19:11
Hey, I read a lot of blogs on a daily basis and for the most part, people lack substance but, I just wanted to make a quick comment to say GREAT blog!.....I"ll be checking in on a regularly now....Keep up the good work! Smile
Franchises For Sale
Franchises For Sale
21 February 2010 14:06
Your blog is so informative … ..I just bookmarked you....keep up the good work!!!!
Picture Collage
Picture Collage
22 February 2010 21:39
I personally have embraced the new technologies and the CMS platforms, I think the new tools only make the web designs better. I am glad that new technologies are coming out in web design that make things easier, improved, and better looking for design.
existing franchises for sale
existing franchises for sale
22 February 2010 21:48
Hey very nice blog!!....I'm an instant fan, I have bookmarked you and I'll be checking back on a regular....See ya
Brenda Engelhardt
Brenda Engelhardt
24 February 2010 14:15
I have been visiting related blogs and sites lately and i have to confess you have a nice design and content. I have bookmarked your page and hope to mention your post in my forthcoming blog.
Wealthy Affiliate Review
Wealthy Affiliate Review
26 February 2010 22:24
This is such a great resource that you are providing and you give it away for free. I love seeing websites that understand the value of providing a quality resource for free. It is the old what goes around comes around routine. Did you acquired lots of links and I see lots of trackbacks??
franchises for sale
franchises for sale
1 March 2010 16:46
Hey very nice blog!!....I'm an instant fan, I have bookmarked you and I'll be checking back on a regular....See ya
cant get pregnant
cant get pregnant
1 March 2010 19:03
YES! I finally discovered this internet site! I've been looking just for this article for such a long time!!
Daniel Millions
Daniel Millions
2 March 2010 04:50
Please let me know if you are looking for a writer for your website. You have some good articles and I think I would be a good asset.
Forex
Forex
2 March 2010 15:44
Howdy, i read your blog occasionally and i own a similar one and i was just wondering if you get a lot of spam comments? If so how do you prevent it, any plugin or anything you can advise? I get so much lately it's driving me mad so any assistance is very much appreciated.
stock quotes
stock quotes
2 March 2010 16:47
Finally someone that actually knows what they are talking about - thank you!
loans
loans
3 March 2010 01:08
Finally someone that actually knows what they are talking about - thank you!
Communion Supplies
Communion Supplies
3 March 2010 15:35
Hello,I love reading through your blog, I wanted to leave a little comment to support you and wish you a good continuation. Wishing you the best of luck for all your blogging efforts.
making money on the internet
making money on the internet
3 March 2010 20:13
Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog. I am sure my visitors will find that very useful.
Calabalas Plumbing
Calabalas Plumbing
4 March 2010 11:56
Hello,I love reading through your blog, I wanted to leave a little comment to support you and wish you a good continuation. Wishing you the best of luck for all your blogging efforts.
Kina Volpa
Kina Volpa
4 March 2010 22:03
Think of a bug…any bug. Call it BugA. Now endeavour to think of some other bugs that could be had by BugA. Those other bugs are what I call “Follow-On Bugs”. Now draw a blank about those different bugs. Instead, go detect BugB. I first saw Michael Hunter use a similar term, “Follow-on Failures”, in a blog post. Ever since, I’ve applied the term “Follow-On Bugs”, though I never get wind other testers hash out these. If I’m neglecting a finer term for these, let me know. “Down-stream bugs” is not a poor term either. Whatever we call these, I steadfastly believe a key to recognizing which tests to implement in the latest build, is to be aware of follow-on bugs. Don’t log them. The more knowledgeable you become about your AUT, the stronger you will identify follow-on bugs. If you’re not for certain, ask your devs. Great testers have more tests than time to run them. Follow-on bugs may consume time.
sparande
sparande
5 March 2010 12:40
Hi. I just noticed that your website looks like it has a few code errors at the very top of your website's page. I'm not sure if everybody is getting this same error when browsing your blog? I am employing a totally different browser than most people, referred to as Opera, so that is what might be causing it? I just wanted to make sure you know. Thanks for posting some great postings and I'll try to return back with a completely different browser to check things out!
Få mer pengar över
Få mer pengar över
5 March 2010 14:54
Hi. I just noticed that your site looks like it has a few code problems at the very bottom of your site's page. I'm not sure if everybody is getting this same problem when browsing your blog? I am employing a totally different browser than most people, referred to as Opera, so that is what might be causing it? I just wanted to make sure you know. Thanks for posting some great postings and I'll try to return back with a completely different browser to check things out!
boards
boards
5 March 2010 17:28
Dude.. I am not much into reading, but somehow I got to read lots of articles on your blog. Its amazing how interesting it is for me to visit you very often.
Daniel Millions
Daniel Millions
6 March 2010 05:50
Great post I bookmared it on Delicious and submitted on Digg. Hopefully it sends more visitors your way Smile
moon in my room
moon in my room
6 March 2010 06:31
Thanks for taking this opportunity to talk about this, I feel strongly about it and I benefit from learning about this subject. If possible, as you gain data, please update this blog with new information. I have found it extremely useful.
stock prices
stock prices
6 March 2010 20:15
Have you thought about adding some sort of bookmarking buttons or links on blog posts?
free racing games
free racing games
7 March 2010 03:17
Nice blog post.I've bookmarked it already. Take care, Ursula.
replica watches
replica watches
7 March 2010 12:10
Hrmm that was weird, my comment got eaten. Anyway I wanted to say that it's nice to know that someone else also mentioned this as I had trouble finding the same info elsewhere. This was the first place that told me the answer. Thanks.
watch the pacific
watch the pacific
8 March 2010 01:32
Hi.Sorry if my english language is not nice.anyway i really want to say that i like this post very much. thank you!
portable infrared sauna
portable infrared sauna
8 March 2010 03:28
Have you ever considered adding more videos to your blog posts to keep the readers more entertained? I mean I just read through the entire article of yours and it was quite good but since I'm more of a visual learner,I found that to be more helpful well let me know how it turns out! I love what you guys are always up too. Such clever work and reporting! Keep up the great works guys I've added you guys to my blogroll. This is a great article thanks for sharing this informative information.. I will visit your blog regularly for some latest post.
LISA NASH
LISA NASH
8 March 2010 23:56
Hi, i just thought i'd post and let you know your blogs layout is really messed up on the K-Melon browser. Anyhow keep up the good work.
Hypnose
Hypnose
9 March 2010 05:26
Hey rather good weblog!! I will bookmark your internet site and undertake the feeds additionally...

Add comment


(Will show your Gravatar icon)

biuquote
Loading