No trabalho agora tive uma discussão com um colega de trabalho, porque criei uma página que ele considera muito genérico .
A página tem 3 modos (simples, adv e especial) – tem que funcionar assim, porque não escolhemos como a especificação é escrita. em cada modo a página parece diferente (as mudanças não são grandes – mostra / oculta 5 campos de texto em diferentes combinações baseadas no modo).
Meu colega de trabalho acha que deveria ser 3 páginas e quando você alterar algo, você deve apenas mesclar as alterações para outros dois modos.
Os campos agora têm código como rendered="#{mode!=2}"
, etc.
PS Agora a diferença são 5 campos, mas no futuro no1 saiba o quanto será alterado .
Usamos Seam (JSF / Facelets), aqui está o código do pseudo facelet (para torná-lo mais fácil de entender). Não o coloquei em panelGroups para apresentar melhor o problema.
<h:output rendered="mode=2" value="Name: " /> <h:input rendered="mode=2" value="bean.name" /> <h:output rendered="mode=2" value="Surename: " /> <h:input rendered="mode=2" value="bean.surname" /> <h:output rendered="mode!=2" value="Surename: " /> <h:input rendered="mode!=2" value="bean.surname" /> <h:output rendered="mode!=2" value="#{mode==1?"My Name":"My friends name"}" /> <h:input rendered="mode!=2" value="bean.name" />
Dupliquei a versão e ficaria assim (pseudo código)
<c:if test=mode=1> <ui:include view=modeSimple.xhtml> </c:if> <c:if test=mode=2> <ui:include view=modeAdv.xhtml> </c:if> <c:if test=mode=3> <ui:include view=modeSpec.xhtml> </c:if> modeSimple.xhtml <h:output value="Surename: " /> <h:input value="bean.surname" /> <h:output value="My Name" /> <h:input value="bean.name" /> modeAdv.xhtml <h:output value="Name: " /> <h:input value="bean.name" /> <h:output value="Surename: " /> <h:input value="bean.surname" /> modeSpec.xhtml <h:output value="Surename: " /> <h:input value="bean.surname" /> <h:output value="My friends name" /> <h:input value="bean.name" />
Comentários
- Em seu exemplo, por que não ” < h: output renderizado = ” mode! = 2 ” value = ” bean.nameLabel ” / > “?
- @ Lenny222 você diz que não devo fixar as etiquetas no código, mas mantê-las com os dados? : | ou você quis dizer que eu deveria usar i18n? pelo seu código, entendo que você deseja gerar dados, mas este é um formulário com rótulos.
- Para mim, os modelos devem ser estáticos. Tenho a impressão de que a lógica (de negócios) está se infiltrando em seus modelos. Já que você usa código (aparentemente um Bean) para lidar com a lógica de qualquer maneira, eu consideraria lidar com a lógica de negócios lá, se possível.
- O código ” fácil de entender ” frase pode acabar sendo incorreta.
- @ Lenny222 você acha que o formulário deve ser estático e não enviar dados? por que usar formulários então? tabelas são para dados estáticos.
Resposta
Você deve estruturar seus modelos usando as mesmas regras de programação. Isso significa essencialmente extrair elementos de design comuns em arquivos separados para evitar a duplicação e, assim, obter um design mais reutilizável. Essa é a regra nº 1 ( DRY ) e o método é chamado de refatoração em termos de programação.
A segunda regra é que você deve se esforçar para simplicidade e clareza. Deve ser fácil entender o layout e para onde ir quando precisar alterar as coisas.
Seguir a primeira regra ao pé da letra leva a uma decomposição pesada de sua interface em muitos e muitos pequenos fragmentos que podem dificultar a compreensão de como o layout é criado. Você tem que caçar muito para descobrir onde as coisas estão. Isso viola a segunda regra, então você precisa encontrar um equilíbrio entre esses dois opostos.
Mas a melhor abordagem é encontrar uma solução que evite esse problema completamente. Acho que, neste caso, você deve considerar uma abordagem mais simples totalmente . Presumo que seja HTML e você mencionou os estados “simples e avançado” na GUI. Você considerou sempre gerar todos os campos e, em seguida, lidar com a lógica da GUI em JavaScript? Em outras palavras, escreva um código do lado do cliente que oculte e mostre os campos relevantes rapidamente, dependendo de qual modo (estado) ele está?
Isso também tem a vantagem de poder alternar o modo sob demanda sem envolver o servidor e você não tem que comprometer nenhuma das regras. Outra grande coisa é que você pode permitir que os caras do front-end faça essas mudanças sem ter que envolver os programadores de back-end, que geralmente não gostam de perder tempo ajustando e polindo o design e a interação.
Comentários
- Não concordo que JS seja mais simples, por quê? a maioria do meu colega de trabalho não ‘ t sabe cada vez mais os frameworks web JS e Java permitem que você ignore JS (Richfaces, GWT ). Quase todas as empresas não se importam com JS (acho que me fizeram uma pergunta sobre JS em todas as empresas em que fiz uma entrevista). Portanto, meus colegas de trabalho não tocariam nesse código e apenas o reescreveriam se tivessem para alterá-lo. Sua ideia é boa, mas não é realista. Além disso, por que manter parte de sua lógica em java e parte em JS? Acho que essa é a razão pela qual os stored procedures morreram (e eu li ke-los).
- @ 0101 Eu não ‘ disse que JS é mais simples ou mais difícil do que qualquer coisa. Depende de suas habilidades. Com um codificador html competente, isso não seria problema. Eu disse que, ao adiar os problemas da GUI para a camada da GUI (onde ele pertence), você geralmente acaba com uma solução muito mais simples. Isso ocorre porque as GUIs são altamente dinâmicas e interativas, linguagem para a qual JS foi criada. Só porque você acha que ” nenhuma empresa se preocupa com JS “, não ‘ não faz meu ponto é menos válido.
- Acho que sim, a questão é o que fazer na minha situação e sua resposta é como ” usar procedimentos armazenados ” e isso não é válido, pois ninguém está usando e seria difícil entender por que eu os teria usado. Eu ‘ estou perguntando qual caminho é melhor para o futuro, já que ‘ não estou 100% certo de que minha escolha é a melhor (agora o a melhor maneira é ignorar colegas de trabalho irritantes).
- @ 0101: Trabalhar com web e HTML implica mais ou menos em JavaScript (e HTTP, CSS e imagens …), então você pode ‘ Não me culpe realmente por presumir que JavaScript era uma opção. É ‘ não como eu ‘ estou pedindo que você escreva em Swing.
- ” Quase todas as empresas não se importam com JS ” – você acredita mesmo nisso? Interfaces ricas na web têm se movido na direção do lado do cliente por muitos anos. Sinto que você está perdendo o ponto principal.
Resposta
Sem ver o código, só posso especular, mas eu acho que no momento seu código está “no limite”.
Para 2 ou 3 modos com um número limitado de mudanças entre os modos que você tem agora provavelmente está OK. No entanto, se fosse mais complicado, então parece que deveria ser refatorado em páginas separadas.
Pessoalmente, eu prefiro um código fácil de entender – é muito mais fácil de manter, tanto para outros desenvolvedores quanto para você quando você tem que pegá-lo novamente 6 meses depois.
No entanto, não há sentido em refatorar o código agora para resolver um problema que pode não existir no futuro . Você diz que não sabe o quanto os requisitos vão mudar – e isso não inclui mudanças – então, aplicando YAGNI (Você não vai precisar disso) não faça nada agora.
Marque o código como exigindo atenção no futuro para que você não se esqueça, mas não altere (e potencialmente quebre) agora.
Comentários
- + 1 – Em caso de dúvida, escolha o fácil de entender. A preocupação no fundo de sua mente sobre se você deve torná-lo genérico é a maneira natural de dizer que você não deve ‘ t.
Resposta
Eu fiz praticamente a mesma coisa. Acredite em mim, depois de implementar alguns comportamentos diferentes para cada modo, a “página principal” se torna uma bagunça quase impossível de ler. Você veria então apenas um monte de blocos de controle de fluxo (logo seguidos pela chuva digital Matrix). Eu me peguei removendo alguns blocos apenas para ter uma visão clara do que está dentro de um determinado modo.
Então, as “páginas separadas” são o caminho a percorrer. No entanto, quando você faz isso, você precisa ” lute contra o “problema de duplicação de código. É aqui que seu colega pode estar errado ao sugerir mesclagens. Infelizmente, eu também fiz isso. Basicamente, ele funciona, mas consome muito tempo precioso e, eventualmente, devido à mesclagem inadequada, a “área comum” das páginas fica fora de sincronia e a mesclagem se torna um verdadeiro pesadelo. Portanto, você está certo em contestar uma fusão como uma solução razoável.
Como você pode ver em muitas respostas, a abordagem correta é extrair partes verdadeiramente “comuns” para entidades externas (fragmentos de página JSP, fragmentos JSF, seja o que for) e incluí-los nessas páginas.
Comentários
- o problema real de que o código comum são apenas os controles h: inputText + h: outputText para campo único. Eu sinto que não vale a pena lutar contra isso. além disso, esta página pode morrer por não ser realmente funcional, por causa dos modos e por ser confusa até mesmo para outros desenvolvedores (do ponto de vista do usuário).
- Então o problema é realmente quando fazer a transição. Você deve reconsiderar a divisão após cada modificação. Quando a página começar a ficar confusa – divida-a. Acho que seu colega de trabalho também ficará mais confortável se você considerar a ideia dele boa, mas ainda não vale a pena implementá-la.
Resposta
A duplicação de código praticamente nunca é uma coisa boa. Dito isso, uma pequena quantidade duplicada não muito mais do que duas vezes é aceitável na vida real – é melhor ser pragmático do que religioso sobre isso. No seu caso, parece uma quantidade maior de código e 3 lugares, então está um pouco acima do meu limite pessoal. Portanto, me inclino para a versão genérica.E, de qualquer forma, se funcionar agora, não há necessidade de tocá-lo apenas por razões teóricas.
OTOH quando você diz que pode haver mais diferenças entre as páginas no futuro, isso pode significar que em algum momento, torna-se mais econômico alternar para páginas separadas (enquanto se esforça para minimizar a duplicação entre elas, extraindo pontos em comum, tanto quanto possível). Portanto, reavalie a situação antes de cada mudança futura.
Resposta
Parece JSF. Cada renderizado = “…” significa essencialmente que você tem um if em seu código, o que causa complexidade adicional.
Eu fiz a mesma coisa porque “é a mesma página, apenas com algumas diferenças aqui e aí “e de forma muito simples, não funciona a longo prazo porque não é” t a mesma página e você precisará fazer truques cada vez mais elaborados para fazê-la funcionar corretamente, fazendo com que seja desnecessariamente difícil de manter.
Se você usar JSF com facelets em vez de JSP (que você deveria, se possível), então você pode construir fragmentos XML correspondentes a um bloco da página, que você pode incluir onde for necessário. Isso comprará modularidade e ainda permitirá que você reutilize o conteúdo nas páginas.
Ouça seu colega de trabalho. Ele está certo.
Comentários
- veja minha edição
- @ 0101, eu suspeito exatamente isso. Não ‘ faça isso, é o caminho para a loucura – provavelmente para você – um e certamente para futuros mantenedores.
- o verdadeiro problema é que meu jeito é o melhor jeito. se eu fizesse 3 páginas então alguém poderia mudar apenas uma das páginas e não pensar nas outras. Eu gostaria da minha versão como um futuro mantenedor.
- Acho que meu código está fazendo o futuro mantenedor pensar em outros casos. Se você fosse um novo programador do projeto e no depurador descobrisse que precisa alterar o código em baseFormBasic.xhtml, também mudaria em baseFormAdv e baseFormSpec?
- @ 0101, por que perguntar o que é melhor, se você apenas deseja que sua opinião preconcebida seja confirmada?
Resposta
Existe uma chance de gerar a página usando código? Nesse caso, que tal algo como:
page1 = { showField1 = true; showField2 = false; showField3 = true; } page2 = { showField1 = true; showField2 = false; showField3 = false; }
E no código de renderização da página
if page.showField1 then .... if page.showField2 then ....
Ou no estilo OOP:
class Page1 { renderField1() { ...} renderField2() {} renderField2() { ...} } class Page2 { renderField1() { ...} renderField2() {} renderField2() {} }
Comentários
- não, não há mudança . Eu seria crucificado se o fizesse. além disso, cria exatamente o mesmo problema. if == renderizado.
- Não é o problema exato, pois extrai a lógica da página. Fazendo apenas uma tarefa, em vez de duas.
- talvez, mas sinto que é o mesmo. meu motivo é que mostrar campos é apenas uma coisa que é diferente, também há diferentes posicionamentos e, às vezes, rótulos. além da programação da web, então eu posso ‘ fazer assim.
Resposta
código modal só pode ficar pior . Classifique e decida uma vez no início e desvie para limpar implementações sem modos.
Comentários
- isn ‘ t pior? todo o código deve estar sempre sincronizado entre si (se você alterar simples, lembre-se de alterar antecipadamente e se esquecer?)
- isole o código comum em sub-rotinas, funções, classes auxiliares / base, etc. ; em OOP, o código modal é uma indicação de classes ausentes …
Resposta
A essência desta pergunta parece ser: quando você tem três páginas da web muito semelhantes com algumas pequenas diferenças, é melhor duplicar essas três páginas e modificar cada uma conforme necessário, ou construir em uma única página a lógica para renderizar dinamicamente a página de acordo com qual “modo “está sendo visualizado.
Para que conste, sou um cara de JSF e gosto disso, e uso renderização condicional.
Se você optar por três páginas, existe o risco de que, conforme as mudanças acontecem, o mantenedor não as aplique corretamente a todas as três páginas.
Se você optar por usar a renderização condicional, você resolve esse problema, mas moveu alguma lógica de negócios para a sua página que pode precisar de alguma reflexão.
Eu pessoalmente não teria nenhum problema com o uso de renderização condicional, mas realmente gostaria de ver a lógica do modo movida para um bean de apoio, por exemplo: em vez de:
<h:output rendered="mode=2" value="Name: " />
Eu gosto:
<h:output rendered="#{myBean.advancedMode}" value="Name: " />
Onde o bean lida com o lógica e retorna verdadeiro ou falso para controlar a renderização do elemento.
A razão é que o modo que está sendo visualizado pode precisar controlar mais do que apenas esta página, pode precisar persistir além da sessão única do usuário, ou você pode precisar alterar os modos completamente no estrada.
Ou você pode aceitar que qualquer uma das abordagens tem desvantagens em potencial, e todas as desvantagens parecem ser relacionadas a aliviar dores no futuro, e concorda em se preocupar mais com isso quando uma daquelas coisas “no futuro” surja e tome decisões melhores, agora que se sabe mais sobre como os requisitos podem mudar.