É uma boa idéia projetar uma arquitetura pensando que as classes da interface do usuário podem ser substituídas por uma interface da linha de comando?

92

Na página 25 do Code Complete, diz-se que é uma boa ideia poder substituir facilmente as classes regulares da interface do usuário por uma linha de comando.

Conhecendo suas vantagens nos testes, e os problemas que isso pode trazer?

Esse trabalho extra realmente compensa para projetos na Web e para dispositivos móveis? E os pequenos e médios projetos; as mesmas regras se aplicam? E se tornar seu design mais complexo?

Julio Rodrigues
fonte
2
No Perl, é exatamente para isso que servem ferramentas como MooseX :: Getopt e Plack :: Handler :: CLI .
Éter
4
Se você criar seu programa com uma CLI primeiro, a interface do usuário poderá ser colocada em camadas, oferecendo muito mais flexibilidade do que uma interface do usuário profundamente incorporada ao programa. É o mesmo para os serviços da web.
precisa saber é o seguinte
28
Sempre é uma palavra forte.
Mark Canlas
8
Observe a cotação original, que é: "A arquitetura deve ser modularizada para que uma nova interface do usuário possa ser substituída sem afetar as regras de negócios e as partes de saída do programa. Por exemplo, a arquitetura deve facilitar bastante o corte de um grupo de classes de interface interativa e conecte um grupo de classes de linha de comando ". Portanto, o CC não diz que você deve se preparar para substituir uma GUI por uma linha de comando, apenas diz que a arquitetura deve acomodar a alteração da interface do usuário. A coisa da linha de comando GUI-> é apenas um exemplo.
sleske
2
@Vandell Eu tenho a segunda edição do código completa e isso não é mencionado na página 25. A que edição você está se referindo?
JW01

Respostas:

43

Ser capaz de reutilizar a funcionalidade em diferentes interfaces (por exemplo, GUI x CLI x REST) ​​nem sempre é necessário, mas é bom ter e permitir a reutilização acidental de um sistema, pois outras pessoas encontram novas maneiras de interagir com ele.

Isso tem algumas desvantagens que precisam ser ponderadas:

  1. Exigirá camadas de abstração adicionais (às vezes até camadas). Embora essas camadas sejam boas práticas de engenharia, elas têm um custo adicional no desenvolvimento, entendendo que isso pode não reduzir o esforço em outras áreas (por exemplo, manutenção, reutilização, teste), por isso vale a pena pensar um pouco sobre isso.
  2. O fluxo ideal para um meio pode ser horrível para outros. Se a funcionalidade foi projetada para oferecer suporte a uma GUI, pode ser muito falador para a web . Nem todas as funcionalidades valem a pena em todos os meios.
  3. Existe uma armadilha na tentativa de definir um conversor genérico entre serviços e interface do usuário, para que se possa definir o contrato de serviço e derivar automaticamente (ou o máximo possível) a interface do usuário para todas as mídias. Muitos projetos desperdiçaram muito esforço tentando construir essas estruturas e adicionando toda a personalização possível à medida que os requisitos mudavam.

Dito isto, na minha experiência em implementar essas camadas sempre acabava pagando o esforço. Em alguns casos, consegui implantar sistemas no prazo porque acabamos tendo que trocar a mídia (por exemplo, da integração de serviços da Web à interface do usuário) algumas semanas antes da data de vencimento.

Daniel Yokomizo
fonte
2
Como outros comentários observaram, deve aumentar a coesão do código e reduzir o acoplamento. Ambos devem tornar seu código mais simples e mais fácil de testar. O fluxo é mais um conceito de GUI e, geralmente, não deve estar presente em outras funcionalidades.
BillThor
Não acredito que isso ainda não tenha sido mencionado, mas essa é a essência da arquitetura Model-View-Controller. O objetivo é ser capaz de trocar visualizações e controladores à vontade, para reduzir o acoplamento, como diz o @BillThor. Este é o melhor caso de uso para MVC.
Rudolf Olah
110

Completamente além do teste, a vantagem óbvia dessa abordagem é que ela tornará seu projeto automatizável e programável . Se eu sou capaz de enviar comandos de linha de comando para um programa, posso escrever um script para executar tarefas complicadas com muito mais facilidade (e com mais segurança!) Do que criar uma macro para automatizar a mesma coisa em uma GUI.

Se vale a pena fazer isso, é claro, depende inteiramente de você ter ou não muitos usuários que desejam automatizar seu programa.

Mason Wheeler
fonte
12
Muitos aplicativos usam um modelo de plug-in para scripts. Normalmente, o modelo de objeto é exposto e uma linguagem como python é usada para escrever os scripts. Não acho que os parâmetros da linha de comando funcionem para um aplicativo não trivial.
softveda
Outro benefício pode ser a descoberta. O recurso Ctrl-Shift-P do Sublime Text é um exemplo fantástico disso. Se houver alguma funcionalidade obscura que eu queira, em vez de procurar nos menus, basta digitar o que acho que seria chamado e posso ver o comando (e o atalho) e sou capaz de executá-lo imediatamente.
23912 Adam Iley
O OpenDJ, um servidor LDAP baseado em java de código aberto é um ótimo exemplo disso: a linha de comando para todas as modificações que você faz na GUI está disponível na caixa de diálogo de confirmação.
22412 Franck
1
@ Marnixv.R .: os gestos são apenas uma maneira conveniente de executar alguma ação que pode ser especificada por um comando, por exemplo, 'Amplie 35.73N 118.23W'. Um desenho pode ser inserido como comandos, embora seja inconveniente. Ainda acho que há grande utilidade em uma interface convenientemente programável e muito pouco trabalho necessário para criar uma.
Kevin cline
7
+1: Outra vantagem importante é que facilita o registro das ações do usuário, simplificando a reprodução dos problemas de produção.
Kevin cline
81

Não é um trabalho extra, apenas um trabalho diferente . Se você fizer o que é certo, não apenas não o tornará mais complexo, como também o tornará mais simples, porque forçará você a desacoplar seu design. Independentemente de você implementar ou não a CLI, seu design será melhor para possibilitar isso.

Karl Bielefeldt
fonte
4
-1 para várias instruções completamente incorretas. Claro que isso tornará mais complexo. Afinal, é um requisito / recurso adicional.
Boris Yankov
@BorisYankov Eu acho que ele quis dizer "complicado" em vez de "complexo" - soam semelhantes e têm sobreposição de significado, de modo que eles são fáceis de confundir de vez em quando
Izkata
43

Uma vantagem importante que parece não ter sido mencionada é que a capacidade de fazer isso impõe uma dissociação rigorosa da interface do usuário do código subjacente. Uma das principais vantagens disso é que, se você precisar alterar significativamente a GUI (por exemplo, padrões do iOS para padrões OSX ou um mecanismo gráfico para outro), é tudo o que você precisará alterar, pois o código subjacente não depende o layout da interface do usuário. Não pode ser porque, se fosse, as ferramentas de linha de comando não funcionariam.

Fora isso, ser capaz de automatizar testes é uma vantagem importante.

deworde
fonte
Corrija-me se estiver errado, mas mudar de uma GUI para outra ainda exigiria um trabalho significativo em termos de validação de formulário / exibição de mensagens de erro, configuração de manipuladores de eventos etc.
Click Upvote
5
Sim, mas toda essa validação faz parte de uma boa interface do usuário, que eu disse que você precisa alterar. O código de back-end que armazena (por exemplo) o estado atual da conta do usuário, o algoritmo para pesquisar itens, as regras específicas do jogo etc. O principal aqui é que, se eu tiver que mudar da interface do usuário baseada em mouse / teclado para interface do usuário com tela sensível ao toque para um jogo, ainda devo poder usar o mesmo mecanismo de back-end para lidar com cálculos e pontuação de combate, para poder me concentrar em escrever novos manipuladores de eventos que usem o mesmo sistema subjacente.
deworde
2
isso não é nada fácil, eu odeio escrever manipuladores de eventos e código de validação de formulário muito mais do que código comercial. (embora eu concorde com você que eles devem ser acoplados da maneira que você descreveu)
Click Upvote
2
@ClickUpvote Até certo ponto, depende de como você implementa sua GUI. Uma GUI realmente fina que apenas envia mensagens ValueChanged para uma classe de suporte e recebe mensagens ValueValid / ValueInvalid em resposta será muito mais fácil trocar por uma que faça toda a validação nos eventos OnTextboxChanged.
Dan Neely
@ClickUpvote Concordo plenamente, é por isso que quero ser capaz de focar naquilo que gosto incorruptivelmente, ou dar o que odeio toda a minha atenção, para que eu possa acabar com isso o mais rápido possível.
deworde
17

Sim, é quase sempre uma boa ideia.

Se você seguir essa abordagem, provavelmente não terá uma lógica de negócios ou acesso a dados em um mesmo encadeamento que a GUI e atrás de algum manipulador de GUI. Só por isso vale a pena investir.

Codificador
fonte
2
Qual seria a vantagem disso, se você estiver escrevendo, por exemplo, um editor de texto?
Nikie 22/08/12
5
@nikie Como, por exemplo, você pode substituir a visualização do editor de texto WYSIWIG por um front-end baseado em texto sem formatação ou marcação, e desde que ele passe as mesmas informações para o modelo subjacente, sua infraestrutura existente continuará funcionando.
deworde
5

Eu acho que é uma boa ideia. Além disso, a capacidade de escrever um segundo front end de linha de comando prova que a lógica de negócios está totalmente dissociada de qualquer arquitetura específica do servidor de aplicativos.

Tulains Córdova
fonte
5

O único perigo que vejo ao fazer isso é que, para chegar a uma determinada parte da interface do usuário, o usuário normalmente precisa percorrer outras partes da interface do usuário.

Onde, como o desenvolvedor, basta executar a interface do usuário diretamente. Vi situações em que um desenvolvedor não conseguia reproduzir um problema dos usuários até que eles realmente usassem o produto.

Então, considere isso também ao criar testes.

Simon O'Doherty
fonte
3

Não. Terrível conselho.

É um pouco yagni (você não vai precisar disso).

Expor uma interface de linha de comando não é o mesmo que estruturar seu aplicativo de uma maneira que ofereça suporte ao teste de unidade ou esteja em conformidade com qualquer parte do SOLID ou com qualquer prática de programação que eu recomendo.

Não funciona para nenhuma interface do usuário que não se adequa a uma interface de linha de comando. O MS Paint é um aplicativo realmente simples, mas como, em qualquer situação, você consideraria um benefício poder controlá-lo a partir de uma linha de comando?

Isso não ajudaria a implementar scripts. Na verdade, isso impediria qualquer progresso nessa direção.

A única coisa positiva é que apareceu na página 25, então pelo menos você recebe um aviso de que o resto do livro pode ser ... fedido. Eu li há muito tempo e não gostei, então sou tendenciosa.

Ian
fonte
1
Concordou +100000000
4
MSPaint com scripts parece realmente útil na verdade.
RoundTower 23/08/12
IMO a melhor resposta. Desde que sigo o mantra "não implemente 'YAGNI'", tenho muito mais tempo concentrando-me no trabalho real e ainda tenho tempo suficiente para experimentar muito. Tentar ser inteligente com antecedência me mostrou que na maioria das vezes o cliente queria uma extensão diferente da mencionada anteriormente, para que não perdesse tempo com algo que não era necessário.
precisa saber é o seguinte
PSPaint + interface de linha de comando = AutoCAD
Vorac 30/08/2012
-1 (se eu pudesse) Observe que não diz "implementar uma CLI, assim como uma GUI"; diz "atenda à implementação de uma interface do usuário alternativa, como uma CLI".
Mark Hurd
2

Com base no que Mason Wheeler disse, ser capaz de interagir com um aplicativo por meio de uma linha de comando facilita muito a automatização de tarefas.

Isso é particularmente útil nos testes.

Para dar um exemplo prático, se eu quiser executar testes automatizados em um aplicativo, convém instalar o aplicativo automaticamente. Para fazer isso, posso passar os seguintes parâmetros, "myApplication.exe / silentinstall".

Posso programá-lo para que, quando especificar essa opção da linha de comandos, uma instalação seja executada silenciosamente em segundo plano, sem o instalador da GUI. Qualquer entrada para o instalador (como o diretório de instalação) pode ser obtida de um arquivo XML, talvez.

Veja outro exemplo. A GUI do Microsoft Test Manager (fornecida com o Visual Studio) permite que os usuários iniciem execuções de teste a partir de sua interface GUI, mas também fornece uma interface de linha de comando para fazer a mesma coisa (usando uma combinação de opções e entradas de linha de comando). Isso significa que eu posso juntar um script do PowerShell ou DOS para automatizar o lançamento de testes e criar uma tarefa agendada para que os scripts sejam executados todas as noites, talvez.

Alguns aplicativos possuem opções de linha de comando que especificam a abertura de um aplicativo com determinadas opções (por exemplo, eu posso usar '/ maximize' para abrir o aplicativo em uma janela maximizada).

Existem muitos cenários em que uma interface de linha de comando pode ser usada. Estes são apenas alguns exemplos.

CiaranG
fonte
1

Observe a frase novamente: "[É] uma boa idéia poder substituir facilmente as classes regulares da interface do usuário por uma linha de comando". Isso não significa que você precise escrever uma CLI, apenas que você poderia fazê-lo facilmente.

Portanto, o que diz é que sua interface do usuário deve ser dissociada do restante do código.

José Dinuncio
fonte
2
Eu acho que você pretendia fazer um comentário, certo?
Julio Rodrigues
1

Depende e quando digo que depende, não se trata apenas de ter alguns casos extremos, mas é muito dependente do aplicativo e do público-alvo. Supondo que estamos eliminando jogos da equação, ainda existe uma grande variedade de aplicativos que você pode estar escrevendo, onde um comando como é improvável ou nunca será implementado. Em primeiro lugar, qualquer aplicativo direcionado a um ambiente móvel (por exemplo, iOS, Android, etc.) provavelmente se enquadra nesse cabeçalho.

Com isso em mente, no espaço geral do software, é improvável que algum aplicativo que dependa muito da visualização (por exemplo, PowerPoint, Maya etc.) veja uma substituição da linha de comando ser implementada. De fato, no caso de softwares gráficos como o Maya, é discutível um bom exercício mental para determinar como uma versão completa e adequada da linha de comando funcionaria e talvez não seja possível fazê-lo do ponto de vista do usuário. Portanto, é claro que existem aplicativos definitivamente comuns que podem ser encontrados nos casos em que é improvável que alguma vez seja vista uma interface de comando ou desejável, mesmo que o script do aplicativo seja desejável.

Em seguida, se olharmos para o formulário sugerido do ponto de vista da arquitetura geral de software, posso ver onde faria sentido periodicamente se perguntar "Como posso acessar esse recurso sem a interface do usuário?" Em geral, se não houver maneira de fazê-lo e ele não estiver interagindo diretamente com o usuário (por exemplo, entrada de gestos), você provavelmente terá uma situação em que a arquitetura geral precisará ser aprimorada. Para facilitar o teste, você deseja acessar diretamente o comando sem passar pela interface do usuário, mesmo que eles não possam ser chamados por uma linha de comando. Isso geralmente significa que uma API sólida precisa estar em vigor e, teoricamente, uma boa API deve permitir o acesso via linha de comando ou interface do usuário. Além disso, a longo prazo,

No final do dia, acho que o que a sugestão está tentando fazer faz sentido (por exemplo, tenha uma boa API e crie sua interface com o usuário), mas a seleção de palavras pode ter sido um pouco melhor para entender o ponto .

rjzii
fonte
1
Eu não discordo em geral, mas um dos pontos fortes do Maya é o fato de ele ter, de fato, uma API de script muito forte (originalmente MELScript, agora Python).
jwd
@jwd - O Maya é um exemplo que escolhi porque o usei há alguns anos, se você tiver um melhor na mesma linha de pensamento, me avise. Talvez Bryce, embora não seja tão bem conhecido?
Rjzii
0

Depende.

Freqüentemente particionamos nossos programas como model / view / controllers ou model / view / view / model. Parece que o modelo deve permitir acesso à linha de comando, mas não tenho tanta certeza sobre o controlador. Naturalmente, a visão é o que está sendo substituído.

Alguma diferença pode existir com base na cadeia de ferramentas. Code Complete é um livro da Microsoft Press, talvez você esteja usando as tecnologias da Microsoft para esta GUI? Nesse caso, acho que pode haver uma caixa de seleção quando você cria o aplicativo para expor interfaces via COM ou DCOM. Para algumas tecnologias da Microsoft, acho que as tabelas de recursos e a passagem de mensagens são muito intensamente acopladas a qualquer coisa que os assistentes o ajudem a criar protótipos rapidamente. Eu acho que está melhorando, mas se você estiver mantendo MFC ou Forms, isso pode doer um pouco.

Em alguns casos, seu programa baseado em GUI pode ser um invólucro em torno de uma interface de gerenciamento ou pode ter tão pouca lógica própria, que não há muito a controlar pela interface da linha de comandos. A criação de um aplicativo de console separado pode ser mais rápido e ainda permitir que você faça scripts, teste ou use o que é importante.

O ponto-chave, eu acho, é que a sugestão não é uma regra. Se você o seguir, deverá obter testes de unidade e aceitação mais fáceis ou uma interface de retorno para quando você ou um cliente podem preferir digitar em vez de clicar. Se ele se paga, faça. Boa sorte.

DesenvolvedorDon
fonte
4
-1: Code Complete é um livro independente de idioma sobre programação.
deworde
1
Ele nunca disse o contrário.
Click Voto a favor
E a pergunta dele era específica para o desenvolvimento da interface do usuário ... Seu ponto, Sr. Deworde?
22412 Ian
0

Depende da utilidade do programa de linha de comando. Algumas coisas, como traçar uma rota em um mapa ou jogar um jogo em 3-d, simplesmente não se prestam a uma interface de linha de comando. Mas outras coisas, como ferramentas de sistema, são muito melhores na linha de comando do que em uma GUI, pela simples razão de que elas podem ser scripts.

O Dr. Richard Hipp disse uma vez que seu sistema operacional GUI ideal era uma área de trabalho em branco com um ícone para abrir janelas de comando e outro ícone para abrir um navegador da web. Eu me sinto quase da mesma maneira. Se fosse útil como um programa de linha de comando e não muito difícil de construir dessa maneira, eu o faria. A GUI pode ser um programa completamente separado, talvez criado por outra pessoa!

GlenPeterson
fonte
Por que a plotagem de uma rota em um mapa não se presta à automação da CLI? Algo como PlotRoute(startPoint, endPoint)é bem direto.
Mason Wheeler
@MasonWheeler - Eu acredito que seria mais parecido com #PlotRoute(startPoint, endPoint, chart)
Fabricio Araujo
0

Atualmente (pelo menos para Java), parece que mais cedo ou mais tarde todos os programas adicionam um serviço da Web (SOAP ou Ajax ou ambos), mais cedo ou mais tarde. Então, em geral, sim, pense assim, mas um front end de serviço da web é mais provável que uma linha de comando, se você quiser uma melhor metáfora mental ... e mais provável.

ArtB
fonte
0

Existe uma maneira diferente de ver as coisas. Em vez de assumir que uma linha de comando é o único caminho a seguir, por que não assumir que o controle de fala possa ser usado? Um paradigma completamente diferente é necessário então.

Antes de Jobs assumir a Apple, mecanismos sofisticados de controle de voz estavam sendo explorados. A Apple reprimiu isso em favor de coisas como a Siri.

Suspiro.

Popular e óbvio nem sempre são "melhores".

Siajanai
fonte
Uma das principais razões para a linha de comando é principalmente poder testar e criar scripts da funcionalidade do software. Pode ser um pouco estranho (ou pelo menos muito complicado) gravar clipes de áudio de nossas vozes apenas para testar o software da unidade ou executar um script em lote.
0

Geralmente é uma boa ideia, sim.

Por metáfora, as pessoas podem pensar nisso como uma forma de design RESTful. .... não é, por si só, como uma interface do usuário típica (G) poderia envolver transações complexas de vários estágios, como a criação de contas.

Better that one stays away from multi-stage complexity through shopping-cart-like models for transactional setup.

Certa vez, programei uma metáfora da interface do usuário do tipo arrastar e soltar no navegador. Regras de interação muito complexas no back-end para fazer com que o UX pareça natural. Resolvi isso tornando o site uma API e a GUI era um aplicativo completo que gerava eventos após a ação. Um módulo capturou esses eventos e, em um timer, os agrupou em 'chamadas de API' (para eficiência da rede).

O resultado foi um sistema principal completamente RESTful. O segundo resultado foi que eu tinha uma interface para terceiros, que eu poderia expor usando perfis de afiliação conforme o modelo de negócios.

NewAlexandria
fonte
-1

Uma vantagem é que você será forçado a pensar no fluxo da interface do usuário da perspectiva do usuário. (O que estou tentando alcançar? Que contexto preciso configurar? Dado esse contexto, como faço para atingir a meta?)

Há uma grande diferença entre "criar conta bancária" e "escrever documento do ms word". Mesmo se você não criar uma CLI, ela poderá agregar valor apenas para considerar o "contexto da CLI" necessário. Os modelos não vivem apenas no modelo de objeto de negócios!

Aswidi
fonte