Pergunta

Quais são suas opiniões sobre o desenvolvimento primeiro para a linha de comando e, em seguida, adicionar uma GUI após o fato, simplesmente chamando os métodos da linha de comando?

por exemplo.

W:\ todo AddTask "reunião com John, re:login revisão por pares" "Escritório de John" "22/08/2008" "14:00"

cargas todo.exe e chama uma função chamada AddTask isso faz alguma validação e lança a reunião em um banco de dados.

Eventualmente você adiciona uma tela para isso:

============================================================

Event:    [meeting with John, re: login peer review]

Location: [John's office]  

Date:     [Fri. Aug. 22, 2008]  

Time:     [ 2:00 PM]

[Clear]  [Submit]

============================================================

Quando você clica em enviar, ele chama a mesma função AddTask.

Isso é considerado:

  • uma boa maneira de codificar
  • só para os novatos
  • horrendo!.

Termo aditivo:

Estou percebendo uma tendência aqui para "a biblioteca compartilhada chamada pelos executáveis ​​da GUI e da CLI". Existe alguma razão convincente para que eles teriam que ser separados, além do tamanho dos próprios binários?

Por que não chamar o mesmo executável de maneiras diferentes:

  • "todo /G" quando você deseja a interface gráfica completa
  • "todo /I" para um prompt interativo dentro de todo.exe (roteiro, etc.)
  • simples e velho "todo <function>" quando você só quer fazer uma coisa e pronto.

Adendo 2:

Foi mencionado que "da maneira como descrevi as coisas, você precisaria gerar um executável toda vez que a GUI precisasse fazer alguma coisa".

Novamente, essa não foi minha intenção.Quando mencionei que a GUI de exemplo chamava "o mesmo AddTask função", não quis dizer que a GUI chamava o programa de linha de comando todas as vezes.Concordo que isso seria totalmente desagradável.Eu pretendia (veja o primeiro adendo) que tudo isso fosse mantido em um único executável, já que era um pequeno exemplo, mas não acho que meu fraseado excluísse necessariamente uma biblioteca compartilhada.

Além disso, gostaria de agradecer a todos vocês pela sua contribuição.Isso é algo que sempre vem à minha mente e agradeço a sabedoria de sua experiência.

Foi útil?

Solução

Eu iria construir uma biblioteca com um aplicativo de linha de comando vinculado a ela.Depois, você pode criar uma GUI vinculada à mesma biblioteca.Chamar uma linha de comando a partir de uma GUI gera processos externos para cada comando e prejudica mais o sistema operacional.

Além disso, com uma biblioteca você pode facilmente fazer testes de unidade para a funcionalidade.

Mas mesmo que seu código funcional esteja separado do seu interpretador de linha de comando, você pode simplesmente reutilizar a fonte para uma GUI sem ter os dois tipos ao mesmo tempo para executar uma operação.

Outras dicas

Coloque a funcionalidade compartilhada em uma biblioteca e, em seguida, escreva uma linha de comando e um front-end GUI para ela.Dessa forma, sua transição de camada não está vinculada à linha de comando.

(Além disso, esta forma adiciona outra preocupação de segurança:a GUI não deveria primeiro ter certeza de que é o todo.exe CERTO que está sendo chamado?)

Joel escreveu um artigo contrastando esse desenvolvimento ("estilo unix") com o método GUI first ("estilo Windows") alguns anos atrás.Ele chamou isso Biculturalismo.

Acho que no Windows será normal (se ainda não o fez) agrupar sua lógica em assemblies .NET, que você poderá acessar a partir de uma GUI e de um provedor do PowerShell.Dessa forma, você obtém o melhor dos dois mundos.

Minha técnica para programar a funcionalidade de back-end primeiro, sem a necessidade de uma UI explícita (especialmente quando a UI ainda não é meu trabalho, por exemplo, estou projetando um aplicativo da web que ainda está em fase de design) é escrever testes de unidade.

Dessa forma, eu nem preciso escrever um aplicativo de console para simular a saída do meu código de back-end - está tudo nos testes e, diferentemente do seu aplicativo de console, não preciso jogar fora o código dos testes porque eles ainda são úteis mais tarde.

Acho que depende do tipo de aplicativo que você está desenvolvendo.Projetar para a linha de comando coloca você no caminho certo para o que Alan Cooper chama de "Modelo de Implementação" em Os presos estão administrando o asilo.O resultado é uma interface de usuário pouco intuitiva e difícil de usar.

A 37signals também defende projetar sua interface de usuário primeiro em Caindo na real.Lembre-se, para todos os efeitos, na maioria dos aplicativos, a interface do usuário é o programa.O código de back-end existe apenas para suportá-lo.

Provavelmente é melhor começar primeiro com uma linha de comando para ter certeza de que a funcionalidade está correta.Se seus usuários principais não puderem (ou não quiserem) usar a linha de comando, você poderá adicionar uma GUI ao seu trabalho.

Isso tornará seu aplicativo mais adequado para scripts, além de limitar a quantidade de adiantamento Descarga de bicicletas para que você possa chegar à solução real mais rapidamente.

Se você planeja manter a versão de linha de comando do seu aplicativo, não vejo problema em fazer isso dessa maneira - não é perda de tempo.Você ainda acabará codificando a funcionalidade principal do seu aplicativo para a linha de comando e, assim, terá uma grande parte do trabalho realizado.

Não vejo que trabalhar dessa maneira seja uma barreira para uma interface de usuário agradável - você ainda tem tempo para adicionar uma e torná-la utilizável, etc.

Acho que essa forma de trabalhar só funcionaria realmente se você pretendesse que seu aplicativo finalizado tivesse variantes de linha de comando e GUI.É fácil simular uma UI e construir sua funcionalidade nela e embelezar a UI mais tarde.

Concordo com Stu:sua funcionalidade básica deve estar em uma biblioteca chamada a partir da linha de comando e do código GUI.Chamar o executável da UI é uma sobrecarga desnecessária em tempo de execução.

@jcarrascal

Não vejo por que isso torna a GUI "ruim?"
Meu pensamento seria que isso forçaria você a pensar sobre o que a lógica de "negócios" realmente precisa realizar, sem se preocupar muito com o fato de as coisas serem bonitas.Depois de saber o que deve/pode fazer, você pode construir sua interface em torno disso da maneira que fizer mais sentido.

Nota:Não quero iniciar um tópico separado, mas qual é a forma preferida de responder/comentários às suas perguntas?Eu considerei isso e a edição da própria pergunta.

Fiz exatamente isso em uma ferramenta que escrevi e funcionou muito bem.O resultado final é uma ferramenta programável que também pode ser usada por meio de uma GUI.

Eu concordo com o sentimento de que você deve garantir que a GUI seja fácil e intuitiva de usar, então pode ser sensato desenvolver as duas ao mesmo tempo...um pequeno recurso de linha de comando seguido por um wrapper GUI para garantir que você esteja fazendo as coisas intuitivamente.

Se você implementar ambos igualmente, o resultado será um aplicativo que pode ser usado de maneira automatizada, o que considero muito poderoso para usuários avançados.

Eu normalmente começo com uma biblioteca de classes e uma interface gráfica separada, realmente ruim e básica.Como a linha de comando envolve a análise da linha de comando, sinto que estou adicionando muita sobrecarga desnecessária.

Como bônus, isso oferece uma abordagem semelhante ao MVC, já que todo o código "real" está em uma biblioteca de classes.É claro que, em um estágio posterior, refatorar a biblioteca junto com uma GUI real em um EXE também é uma opção.

Se você fizer o desenvolvimento corretamente, será relativamente fácil mudar para uma GUI posteriormente no projeto.O problema é que é meio difícil acertar.

Depende do seu objetivo para o programa, mas sim, eu faço isso de vez em quando - é mais rápido de codificar, mais fácil de depurar e mais fácil de escrever casos de teste rápidos e sujos.E contanto que eu estruture meu código corretamente, posso voltar e adicionar uma GUI mais tarde, sem muito trabalho.

Para aqueles que sugerem que esta técnica resultará em UIs horríveis e inutilizáveis:Você tem razão.Escrever um utilitário de linha de comando é uma maneira terrível de projetar uma GUI.Tome nota, todo mundo está pensando em escrever uma UI que não é um CLUI - não crie um protótipo como um CLUI.

Mas, se você estiver escrevendo um novo código que não depende de uma UI, então vá em frente.

Uma abordagem melhor pode ser desenvolver a lógica como uma biblioteca com uma API bem definida e, no estágio de desenvolvimento, nenhuma interface (ou uma interface codificada), então você pode criar a CLI ou GUI posteriormente

Eu não faria isso por alguns motivos.

Projeto:

Uma GUI e uma CLI são duas interfaces diferentes usadas para acessar uma implementação subjacente.Eles geralmente são usados ​​para finalidades diferentes (a GUI é para um usuário ativo, a CLI geralmente é acessada por script) e muitas vezes podem ter requisitos diferentes.Unir os dois não é uma escolha sábia e certamente causará problemas no futuro.

Desempenho:

Do jeito que você descreveu as coisas, você precisa gerar um executável toda vez que a GUI precisar fazer alguma coisa.Isso é simplesmente feio.

A maneira correta de fazer isso é colocar a implementação em uma biblioteca chamada pela CLI e pela GUI.

John Gruber fez uma boa postagem sobre o conceito de adicionar uma GUI a um programa que não foi projetado para ela: Usabilidade do Ronco Spray-On

Resumo:Não funciona.Se a usabilidade não for projetada em um aplicativo desde o início, adicioná-la mais tarde será mais trabalhoso do que qualquer um está disposto a fazer.

@Maudite

O aplicativo de linha de comando verificará os parâmetros antecipadamente e a GUI não - mas eles ainda verificarão os mesmo parâmetros e inseri-los em algumas funções de trabalho genéricas.

Ainda o mesmo objetivo.Não vejo a versão da linha de comando afetando a qualidade da GUI.

Faça um programa que você expõe como um serviço web.em seguida, execute a interface gráfica e a linha de comando para chamar o mesmo serviço da web.Essa abordagem também permite criar uma web-gui e também fornecer a funcionalidade como SaaS para parceiros de extranet e/ou proteger melhor a lógica de negócios.

Isso também permite que seu programa participe mais facilmente de um ambiente SOA.

Para o serviço web, não exagere.faça yaml ou xml-rpc.Mantenha simples.

Além do que Stu dito, ter uma biblioteca compartilhada permitirá que você a use também em aplicativos da web.Ou mesmo de um plugin IDE.

Existem vários motivos pelos quais fazer isso dessa maneira não é uma boa ideia.Muitos deles foram mencionados, então vou me concentrar apenas em um ponto específico.

As ferramentas de linha de comando geralmente não são interativas, enquanto as GUI são.Esta é uma diferença fundamental.Isto é, por exemplo, doloroso para tarefas de longa duração.

Sua ferramenta de linha de comando imprimirá, na melhor das hipóteses, algum tipo de informação de progresso - novas linhas, uma barra de progresso textual, um monte de saída, ...Qualquer tipo de erro só pode ser gerado no console.

Agora que você quer colocar uma GUI em cima disso, o que você faz?Analisar a saída da sua ferramenta de linha de comando de longa duração?Procure AVISO e ERRO nessa saída para abrir uma caixa de diálogo?

Na melhor das hipóteses, a maioria das interfaces de usuário construídas dessa maneira exibem uma barra de ocupado pulsante enquanto o comando é executado e, em seguida, mostram uma caixa de diálogo de sucesso ou falha quando o comando é encerrado.Infelizmente, é assim que muitos programas UNIX GUI são reunidos, tornando a experiência do usuário terrível.

A maioria dos respondentes aqui está correta ao dizer que você provavelmente deveria abstrair a funcionalidade real do seu programa em uma biblioteca e, em seguida, escrever uma interface de linha de comando e a GUI ao mesmo tempo para ele.Toda a sua lógica de negócios deve estar em sua biblioteca, e qualquer UI (sim, uma linha de comando é uma UI) deve fazer apenas o que for necessário para fazer a interface entre sua lógica de negócios e sua UI.

Uma linha de comando é uma interface de usuário muito pobre para garantir que você desenvolva sua biblioteca suficientemente boa para uso posterior da GUI.Você deve começar com ambos desde o início ou com a programação da GUI.É fácil adicionar uma interface de linha de comando a uma biblioteca desenvolvida para uma GUI, mas é muito mais difícil o contrário, precisamente por causa de todos os recursos interativos que a GUI precisará (relatórios, progresso, caixas de diálogo de erro, i18n, ... )

As ferramentas de linha de comando geram menos eventos que os aplicativos GUI e geralmente verificam todos os parâmetros antes de iniciar.Isso limitará sua interface gráfica porque, para uma interface gráfica, pode fazer mais sentido solicitar os parâmetros enquanto seu programa funciona ou posteriormente.

Se você não se importa com a GUI, não se preocupe.Se o resultado final for uma interface gráfica, faça a interface gráfica primeiro e depois faça a versão da linha de comando.Ou você pode trabalhar em ambos ao mesmo tempo.

--Edição massiva--

Depois de passar algum tempo em meu projeto atual, sinto como se tivesse completado o círculo em relação à minha resposta anterior.Eu acho que é melhor fazer a linha de comando primeiro e depois colocar uma interface gráfica nela.Se precisar, acho que você pode fazer um ótimo gui depois.Ao executar a linha de comando primeiro, você obtém todos os argumentos primeiro, para que não haja surpresas (até que os requisitos mudem) ao executar a UI/UX.

Essa é exatamente uma das minhas realizações mais importantes sobre codificação e gostaria que mais pessoas adotassem essa abordagem.

Apenas um pequeno esclarecimento:A GUI não deve ser um wrapper em torno da linha de comando.Em vez disso, deve-se ser capaz de controlar o núcleo do programa a partir de uma GUI ou de uma linha de comando.Pelo menos no início e apenas nas operações básicas.

Quando isso é uma ótima ideia?

Quando você quiser ter certeza de que a implementação do seu domínio é independente da estrutura da GUI.Você quer codificar em volta o quadro não em o quadro

Quando isso é uma má ideia?

Quando você tem certeza de que sua estrutura nunca morrerá

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top