Em A triste tragédia do teatro de micro-otimização discutimos as considerações sobre o desempenho da criação de um fragmento de HTML.
string s =
@"<div class=""action-time"">{0}{1}</div>
<div class=""gravatar32"">{2}</div>
<div class=""details"">{3}<br/>{4}</div>";
return String.Format(s, st(), st(), st(), st());
O segundo ato desse teatro em particular foi prenunciado pelo O livro de Stephen Touset comentário:
A resposta correta é que se o senhor está concatenando HTML, está fazendo isso errado em primeiro lugar. Use uma linguagem de modelos HTML. As pessoas que mantiverem seu código depois do senhor lhe agradecerão (atualmente, o senhor corre o risco de sofrer qualquer coisa, desde zombaria aberta até danos materiais significativos).
As características de desempenho da criação de pequenos fragmentos de cadeia de caracteres não são apenas uma pista falsa – não, é muito, muito pior. O pergunta inteira está errada. Este é um dos meus favoritos lições do The Pragmatic Programmer.
Ao se deparar com um problema impossível, identifique as restrições reais. Pergunte a si mesmo: “Isso precisa ser feito dessa forma? Tem que ser feito de qualquer maneira?”
Se nossa conclusão final foi que o desempenho é secundário à legibilidade do código, é exatamente isso que deveríamos ter perguntado, antes de fazer qualquer outra coisa.
Vamos expressar o mesmo exemplo de código usando o padrão ASP.NET MVC mecanismo de modelagem. E sim, nós renderizamos coisas como essa em todo o lugar no Stack Overflow. Esse é o método padrão de renderização por um motivo.
<div class="action-time"><%= User.ActionTime %></div> <div class="gravatar32"><%= User.Gravatar %></div> <div class="details"><%= User.Details %><br/><%= User.Stuff %></div>
Temos um arquivo HTML, no qual abrimos alguns buracos e inserimos os dados. Bastante simples e conceitualmente semelhante ao String.Replace
. A modelagem funciona razoavelmente bem nos casos triviais em que o usuário tem um objeto com tipos de dados básicos e óbvios nos campos que são exibidos.
Mas, além desses casos simples, é chocante como os modelos HTML ficam complicados. E se o senhor precisar fazer um pouco de formatação ou processamento para colocar esses dados em forma antes de exibi-los? E se o senhor precisar tomar decisões e exibir coisas de forma diferente dependendo do conteúdo desses campos? Seus modelos de página, que antes eram simples, tornam-se cada vez mais complexos.
<%foreach (var User in Users) { %> <div class="action-time"><%= ActionSpan(User)%></div> <% if (User.IsAnonymous) { %> <div class="gravatar32"><%= RenderGravatar(User)%></div> <div class="details"><%= RepSpan(User)%><br/><%= Flair(User)%></div> <% } else { %> <div class="anon">anonymous</div> <% } %> <% } %>
Esse é um caso bastante moderado, mas o senhor pode ver onde o modelo tende naturalmente a uma mistura frenética e ilegível de código e modelo. Desenvolvimento Web como sopa de etiquetas. Se os seus modelos HTML não puderem ser mantidos simples, eles não serão muito melhores do que o código de construção de string procedural que estão substituindo. E, na minha experiência, não é fácil manter o controle sobre isso. A rotina diária de luta para evitar que os modelos se transformem em uma sopa de tags começa a parecer tão suja quanto todo aquele trabalho desagradável com strings que teoricamente estávamos substituindo.
Agora é minha vez de perguntar… por quê?
Acho que as soluções de modelos existentes estão fazendo isso de forma completamente inversa. Em vez de abrir buracos no HTML para inserir código, deveríamos simplesmente tratar o HTML como código.
Assim:
foreach (var User in Users) { <div class="action-time">[ActionSpan(User)]</div> if (User.IsAnonymous) { <div class="gravatar32">[RenderGravatar(User)]</div> <div class="details">[UserRepSpan(User)]<br/>[UserFlairSpan(User)]</div> } else { <div class="anon">anonymous</div> } }
Mistura perfeitamente código e HTML, usando um mínimo daqueles caracteres de escape que causam dor de cabeça. Essa é uma linguagem de programação para uma raça de super-homens futuristas? Não. Existem linguagens que podem fazer isso agora mesmo, hoje – onde o senhor pode colocar HTML no meio do seu código. Isso já é possível Usando literais XML do Visual Basic, por exemplo.
Até mesmo o hilariantemente difamado X# tem a ideia central correta. A modelagem tende a falhar porque ele força o senhor a tratar o código e a marcação como duas coisas diferentes e fundamentalmente incompatíveis. Passamos todo o nosso tempo alternando desajeitadamente entre a terra da marcação e a terra do código usando sequências de escape. Eles estão sempre lutando entre si – e contra nós.
Ver o HTML e o código receberem o mesmo tratamento em meu IDE me faz perceber uma coisa:
Nós todos estão fazendo isso errado.