¿Es una buena idea diseñar una arquitectura pensando que las clases de la interfaz de usuario se pueden reemplazar por una interfaz de línea de comandos?


92

En Code Complete, página 25, se dice que es una buena idea poder reemplazar fácilmente las clases normales de la interfaz de usuario por una línea de comando.

Conociendo sus ventajas para las pruebas, ¿qué pasa con los problemas que puede traer?

¿Este trabajo extra realmente valdrá la pena para proyectos web y móviles? ¿Qué pasa con los proyectos pequeños y medianos? ¿Se aplican las mismas reglas? ¿Qué pasa si hace que su diseño sea más complejo?


2
En Perl, esto es justo para lo que sirven herramientas como MooseX :: Getopt y Plack :: Handler :: CLI .
Éter

44
Si primero construye su programa con una CLI, la IU se puede superponer encima, lo que brinda mucha más flexibilidad que una IU que está profundamente integrada en el programa. Esto es muy similar para los servicios web.
zzzzBov

28
Siempre es una palabra fuerte.
Mark Canlas

8
Tenga en cuenta la cita original, que es: "La arquitectura se debe modularizar de modo que se pueda sustituir una nueva interfaz de usuario sin afectar las reglas de negocio y las partes de salida del programa. Por ejemplo, la arquitectura debería hacer que sea bastante fácil cortar un grupo de clases de interfaz interactiva y conecte un grupo de clases de línea de comandos ". Por lo tanto, CC no dice que debe prepararse para reemplazar una GUI con una línea de comando, solo dice que la arquitectura debería adaptarse al cambio de la IU. La línea de comando GUI-> es solo un ejemplo.
sleske

2
@Vandell Tengo la segunda edición de Code Complete y esto no se menciona en la página 25. ¿A qué edición te refieres?
JW01

Respuestas:


43

Ser capaz de reutilizar la funcionalidad bajo diferentes interfaces (por ejemplo, GUI vs CLI vs REST) ​​no siempre es necesario, pero es bueno tenerlo y permitir la reutilización fortuita de un sistema, ya que otras personas encuentran nuevas formas de interactuar con él.

Esto tiene algunos inconvenientes que deben ser ponderados:

  1. Requerirá capas de abstracción adicionales (a veces incluso niveles). Si bien tener estas capas es una buena práctica de ingeniería, tienen un costo adicional en el desarrollo, entendiendo que puede no reducir el esfuerzo en otras áreas (por ejemplo, mantenimiento, reutilización, prueba), por lo que vale la pena reflexionar un poco al respecto.
  2. El flujo óptimo para un medio puede ser horrible para otros. Si la funcionalidad fue diseñada para admitir una GUI, puede ser demasiado hablador para la web . No toda la funcionalidad vale la pena en todos los medios.
  3. Hay una trampa al tratar de definir un convertidor genérico entre los servicios y la interfaz de usuario, por lo que uno puede definir el contrato de servicio y derivar automáticamente (o tanto como sea posible) la IU para todos los medios. Muchos proyectos desperdiciaron demasiado esfuerzo tratando de construir dichos marcos y añadiéndole todas las personalizaciones posibles a medida que cambiaban los requisitos.

Dicho esto, en mi experiencia, la implementación de tales capas siempre terminó pagando el esfuerzo. En un par de casos, logré implementar sistemas a tiempo porque terminamos teniendo que intercambiar medios (por ejemplo, desde la integración de servicios web a la interfaz de usuario) unas semanas antes de la fecha de vencimiento.


2
Como otros comentarios han señalado, debería aumentar la cohesión del código y reducir el acoplamiento. Ambos deben hacer que su código sea más simple y más fácil de probar. Flow es más un concepto de GUI y, por lo general, no debería estar presente en otras funciones.
BillThor

No puedo creer que esto no se haya mencionado aún, pero esta es la esencia de la arquitectura Modelo-Vista-Controlador. El punto es poder intercambiar vistas y controladores a voluntad, para reducir el acoplamiento como dice @BillThor. Este es el mejor caso de uso para MVC.
Rudolf Olah

110

Completamente aparte de las pruebas, la ventaja obvia de este enfoque es que hará que su proyecto sea automatizable y programable . Si puedo enviar comandos de línea de comandos a un programa, puedo escribir un script para realizar tareas complicadas mucho más fácilmente (¡y de manera más confiable!) De lo que podría crear una macro para automatizar lo mismo en una GUI.

Si vale la pena hacerlo o no, por supuesto, depende completamente de si tienes muchos usuarios que quieran automatizar tu programa.


12
Muchas aplicaciones utilizan un modelo de complemento para la creación de secuencias de comandos. Por lo general, el modelo de objetos está expuesto y se usa un lenguaje como python para escribir los scripts. No creo que los parámetros de la línea de comandos funcionen para una aplicación no trivial.
softveda

Otro beneficio puede ser la capacidad de descubrimiento. La función Ctrl-Shift-P de Sublime Text es un fantástico ejemplo de esto. Si deseo alguna funcionalidad oscura, en lugar de tener que buscar en los menús, simplemente escribo lo que creo que se llamaría, y puedo ver el comando (y el acceso directo) y puedo ejecutarlo de inmediato.
Adam Iley

OpenDJ, un servidor LDAP de código abierto basado en Java es un gran ejemplo de esto: la línea de comando para cada modificación que realice en la GUI está disponible en el cuadro de diálogo de confirmación.
Franck

1
@ Marnixv.R .: los gestos son simplemente una forma conveniente de realizar alguna acción que podría especificarse mediante un comando, por ejemplo, 'Acercar en 35.73N 118.23W'. Se podría ingresar un dibujo como comandos, aunque sería inconveniente. Aún así, creo que hay una gran utilidad en una interfaz convenientemente programable, y se necesita muy poca mano de obra para crear una.
Kevin Cline

77
+1: Otra ventaja clave es que facilita el registro de las acciones del usuario, simplificando la reproducción de los problemas de producción.
Kevin Cline

81

No es trabajo extra, solo trabajo diferente . Si lo hace bien, no solo no lo hará más complejo, sino que lo hará más simple porque lo obligará a desacoplar su diseño. Independientemente de si implementa o no la CLI, su diseño será mejor para que sea posible hacerlo.


44
-1 para varias declaraciones completamente incorrectas. Por supuesto que lo hará más complejo. Es, después de todo, un requisito / característica adicional.
Boris Yankov

@BorisYankov Creo que se refería a "complicado" en lugar de "complejo": suenan similares y tienen un significado superpuesto, por lo que son fáciles de confundir en ocasiones
Izkata

43

Una ventaja clave que no parece haber sido mencionada es que ser capaz de hacer esto impone un desacoplamiento estricto de la interfaz de usuario del código subyacente. Una ventaja clave de esto es que significa que si necesita cambiar significativamente la GUI (por ejemplo, los estándares de iOS a los estándares de OSX, o un motor gráfico a otro), eso es todo lo que necesita cambiar, ya que el código subyacente no depende de El diseño de la interfaz de usuario. No puede ser, porque si lo fuera, las herramientas de línea de comando no funcionarían.

Aparte de eso, poder automatizar las pruebas es una ventaja clave.


Corríjame si me equivoco, pero cambiar de una GUI a otra aún requeriría un trabajo significativo en términos de validación de formularios / mostrar mensajes de error, configurar controladores de eventos, etc.
Haga clic en Upvote el

55
Sí, pero toda esa validación es parte de una buena interfaz de usuario, que he dicho que necesita cambiar. El código de back-end que almacena (por ejemplo) el estado actual de la cuenta del usuario, el algoritmo para buscar elementos, las reglas específicas del juego, etc. La clave aquí es que si tengo que cambiar de la interfaz de usuario basada en el mouse / teclado a interfaz de usuario con pantalla táctil para un juego, todavía debería poder usar el mismo motor de back-end para manejar los cálculos de combate y la puntuación, para poder concentrarme en escribir nuevos controladores de eventos que usen el mismo sistema subyacente.
deworde

2
eso no es fácil por cierto, odio escribir controladores de eventos y código de validación de formularios mucho más que código de negocios. (aunque estoy de acuerdo con usted en que deben ser acoplados de la manera que usted describió)
Haga clic en Upvote el

2
@ClickUpvote Hasta cierto punto, depende de cómo implemente su GUI. Una interfaz gráfica de usuario realmente delgada que solo envía mensajes ValueChanged a una clase de soporte y recibe mensajes ValueValid / ValueInvalid en respuesta será mucho más fácil intercambiar aquel que hace toda la validación en los eventos OnTextboxChanged.
Dan Neely

@ClickUpvote Estoy bastante de acuerdo, es por eso que quiero poder concentrarme en lo que me gusta sin corrupción, o dar lo que odio toda mi atención, para que pueda terminar con esto lo antes posible.
deworde

17

Sí, casi siempre es una buena idea.

Si sigue este enfoque, es probable que no tenga una lógica de negocios o acceso a datos en un mismo hilo que la GUI, y detrás de algún controlador de GUI. Solo vale la pena invertir en esta razón.


2
¿Cuál sería la ventaja de eso, si está escribiendo, por ejemplo, un editor de texto?
nikie

55
@nikie Debido a que, por ejemplo, podría reemplazar su vista del editor de texto WYSIWIG con un front-end basado en texto o marcado, y siempre que pase la misma información al modelo subyacente, su infraestructura existente continuará funcionando.
deworde

5

Creo que es una buena idea. Además, al poder escribir un segundo front-end de línea de comandos, se demuestra que la lógica empresarial está totalmente desacoplada a cualquier arquitectura de servidor de aplicaciones en particular.


5

El único peligro que veo al hacer esto es que para llegar a cierta parte de la interfaz de usuario, el usuario normalmente tiene que atravesar otras partes de la interfaz de usuario.

Mientras que el desarrollador solo puede ejecutar la interfaz de usuario directamente. He visto situaciones en las que un desarrollador no pudo reproducir un problema de los usuarios hasta que realmente usaron el producto.

Así que tenga eso en cuenta también al crear pruebas.


3

No. Terrible consejo.

Es un poco yagni (no lo vas a necesitar).

Exponer una interfaz de línea de comandos no es lo mismo que estructurar su aplicación de una manera que admita pruebas unitarias o cumpla con cualquier parte de SOLID o cualquier práctica de programación que recomiendo.

No funciona para ninguna interfaz de usuario que simplemente no se adapte a una interfaz de línea de comandos. MS Paint es una aplicación realmente simple, pero ¿cómo, en cualquier situación, verías un beneficio de poder controlarlo desde una línea de comandos?

No le ayudaría a implementar secuencias de comandos. De hecho, obstaculizaría cualquier progreso en esa dirección.

Lo único positivo es que apareció en la página 25, así que al menos recibes una advertencia de que el resto del libro podría ser ... maloliente. Lo leí hace mucho tiempo y no me gustó, así que soy parcial.


1
Acordado +100000000

44
Scriptable MSPaint suena realmente útil en realidad.
RoundTower

OMI la mejor respuesta. Desde que sigo el mantra "no implementar 'YAGNI'", tengo mucho más tiempo concentrándome en el trabajo real y aún me queda tiempo suficiente para experimentar mucho. Intentar ser inteligente de antemano me ha demostrado que la mayoría de las veces el cliente quería una extensión diferente a la mencionada anteriormente, por lo que no se pierde tiempo en algo que no es necesario.
topskip

Interfaz de línea de comandos PSPaint + = AutoCAD
Vorac

-1 (si pudiera) Tenga en cuenta que no dice "implementar una CLI tan bien como una GUI"; dice "atender para implementar una IU alternativa, como una CLI".
Mark Hurd el

2

Sobre la base de lo que dijo Mason Wheeler, poder interactuar con una aplicación a través de una línea de comandos hace que sea muy fácil automatizar las tareas.

Esto es particularmente útil en las pruebas.

Para dar un ejemplo práctico, si quiero ejecutar pruebas automatizadas en una aplicación, es posible que desee instalar la aplicación automáticamente. Para hacer esto, podría pasar los siguientes parámetros, "myApplication.exe / silentinstall".

Podría programarlo para que cuando especifique este modificador de línea de comandos, una instalación se realice de forma silenciosa en segundo plano, sin el instalador de la GUI. Quizás cualquier entrada al instalador (como el directorio de instalación) podría recogerse de un archivo XML.

Toma otro ejemplo. Microsoft Test Manager GUI (viene con Visual Studio) permite a los usuarios iniciar ejecuciones de prueba desde su interfaz GUI, pero también proporciona una interfaz de línea de comandos para hacer lo mismo (usando una combinación de entradas y cambios de línea de comandos). Esto significa que puedo crear un script de PowerShell o DOS para automatizar el inicio de las pruebas, y luego podría crear una tarea programada para que los scripts se ejecuten todas las noches, tal vez.

Algunas aplicaciones tienen modificadores de línea de comandos que especifican que una aplicación se abra con ciertas opciones (por ejemplo, podría usar '/ maximizar' para abrir la aplicación en una ventana maximizada).

Hay muchos escenarios en los que podría usarse una interfaz de línea de comandos. Estos son solo algunos ejemplos.


1

Observe la frase nuevamente: "[Es una buena idea poder reemplazar fácilmente las clases normales de la interfaz de usuario por una línea de comando". No significa que tenga que escribir una CLI, solo que podría hacerlo fácilmente.

Entonces, lo que dice es que su interfaz de usuario debe estar desacoplada del resto del código.


2
Creo que pretendías hacer un comentario, ¿verdad?
Julio Rodrigues

1

Depende y cuando digo que depende, no se trata solo de tener un par de casos extremos, sino que depende mucho de la aplicación y del público objetivo. Suponiendo que estamos eliminando juegos de la ecuación, todavía hay una amplia gama de aplicaciones que puede estar escribiendo donde un comando como es poco probable o nunca se implementará. Fuera de mi cabeza, cualquier aplicación dirigida a un entorno móvil (p. Ej., IOS, Android, etc.) probablemente caiga bajo este encabezado.

Con eso en mente, en el espacio de software general, es poco probable que cualquier aplicación que dependa en gran medida de la visualización (por ejemplo, PowerPoint, Maya , etc.) vea que se implemente un reemplazo de línea de comando. De hecho, en el caso de software de gráficos como Maya, es discutible un buen ejercicio mental para determinar cómo funcionaría una versión completa y adecuada de la línea de comandos y es posible que no sea posible desde el punto de vista del usuario. Por lo tanto, está claro que definitivamente se pueden encontrar aplicaciones comunes en las que es poco probable que se vea un comando como la interfaz, o sea deseable, incluso si las secuencias de comandos de la aplicación pueden ser deseables.

A continuación, si observamos la forma sugerente desde el punto de vista de la arquitectura de software general, puedo ver dónde tendría sentido preguntarse periódicamente "¿Cómo puedo acceder a esta función sin la interfaz de usuario?" En general, si no hay forma de hacerlo y no está interactuando directamente con el usuario (por ejemplo, entrada de gestos), entonces es probable que tenga una situación en la que la arquitectura general necesita ser mejorada. Para facilitar las pruebas, querrá poder acceder directamente al comando sin pasar por la interfaz de usuario, aunque no se puedan invocar a través de una línea de comando. Esto generalmente significa que se necesita una API sólida y, en teoría, una buena API debería permitir el acceso a través de la línea de comandos o la interfaz de usuario. Además, a la larga,

Al final del día, creo que lo que la sugerencia está tratando de obtener tiene sentido (es decir, tener una buena API y construir su interfaz de usuario a partir de eso), pero la selección de palabras podría haber sido un poco mejor para transmitir el punto .


1
No estoy en desacuerdo en general, pero una de las grandes fortalezas de Maya es el hecho de que, de hecho, tiene una API de script muy fuerte (originalmente MELScript, ahora Python).
jwd

@jwd - Maya es un ejemplo que elegí porque lo usé hace un par de años, si tienes uno mejor en la misma línea de pensamiento, házmelo saber. Tal vez Bryce, aunque no es tan bien saber?
rjzii

0

Depende.

A menudo dividimos nuestros programas como model / view / controllers o model / view / view / model. Parece que el modelo debería permitir el acceso a la línea de comandos, pero no estoy tan seguro sobre el controlador. Naturalmente, la vista es lo que está siendo reemplazado.

Puede existir alguna diferencia basada en la cadena de herramientas. Code Complete es un libro de Microsoft Press, por lo que quizás esté utilizando las tecnologías de Microsoft para esta GUI. Si es así, creo que podría haber una casilla de verificación cuando cree la aplicación para exponer interfaces a través de COM o DCOM. Para algunas tecnologías de Microsoft, creo que las tablas de recursos y el paso de mensajes se combinan de manera bastante intensa con cualquier cosa que los Wizards le ayuden a crear prototipos rápidamente. Creo que está mejorando, pero si mantiene MFC o Forms, podría doler un poco.

En algunos casos, su programa basado en GUI puede ser una envoltura alrededor de una interfaz de administración o puede tener tan poca lógica propia, que no hay mucho que controlar mediante la interfaz de línea de comando. La creación de una aplicación de consola separada puede ser más rápida y aún así permitirle escribir, probar o usar lo que es importante.

El punto clave, supongo, es que la sugerencia no es una regla. Si lo sigue, debería obtener pruebas más sencillas de unidad y aceptación o una interfaz alternativa para cuando usted o un cliente prefieran escribir en lugar de hacer clic. Si se paga solo, hágalo. Buena suerte.


44
-1: Code Complete es un libro independiente del lenguaje sobre programación artesanal.
deworde

1
Nunca dijo lo contrario.
Haga clic en Upvote el

Y su pregunta era específica para el desarrollo de la interfaz de usuario ... ¿Su punto, señor Deworde?
Ian

0

Depende de cuán útil sea el programa de línea de comandos. Algunas cosas, como trazar una ruta en un mapa o jugar un juego tridimensional, simplemente no se prestan a una interfaz de línea de comandos. Pero otras cosas, como las herramientas del sistema, son mucho mejores desde la línea de comandos que desde una GUI, por la sencilla razón de que pueden ser programadas.

El Dr. Richard Hipp dijo una vez que su sistema operativo GUI ideal era un escritorio en blanco con un icono para abrir ventanas de comandos y otro icono para abrir un navegador web. Me siento casi de la misma manera. Si fuera útil como un programa de línea de comandos, y no fuera demasiado difícil de construir de esa manera, lo haría. ¡La GUI podría ser un programa completamente separado, tal vez construido por otra persona!


¿Por qué no trazar una ruta en un mapa se presta a la automatización de la CLI? Algo así PlotRoute(startPoint, endPoint)es bastante sencillo.
Mason Wheeler

@MasonWheeler - Creo que sería más comoPlotRoute(startPoint, endPoint, chart)
Fabricio Araujo

0

En estos días (al menos para Java) parece que tarde o temprano todos los programas agregan un servicio web (SOAP o Ajax o ambos) tarde o temprano. Entonces, en general, sí, piense de esa manera, pero es más probable que un front end de servicio web que una línea de comando si desea una mejor metáfora mental ... y una más probable.


0

Hay una forma diferente de ver las cosas. En lugar de suponer que una línea de comando es el único camino a seguir, ¿por qué no asumir que el control del habla podría usarse en su lugar? Entonces se requiere un paradigma completamente diferente.

Antes de que Jobs se hiciera cargo de Apple, se estaban explorando mecanismos de control de voz muy sofisticados. Apple aplastó esto a favor de cosas como Siri.

Suspiro.

Lo popular y lo obvio no siempre son "los mejores".


Una de las principales razones de la línea de comandos es principalmente para poder probar y ejecutar la funcionalidad del software. Puede ser un poco incómodo (o al menos un disco duro) grabar clips de audio de nuestras voces solo para probar el software o ejecutar un script por lotes.

0

Generalmente es una buena idea, sí.

Por metáfora, la gente puede pensar en esto como una forma de diseño RESTful. .... no es, per se, ya que una interfaz de usuario (G) típica podría involucrar transacciones complejas en varias etapas como la creación de cuentas.

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

Una vez programé una metáfora de interfaz de usuario de arrastrar y soltar en el navegador. Reglas de interacción muy complejas en el back-end para que el UX se sienta natural. Resolví esto haciendo del sitio una API y la GUI era una aplicación completa que generaba eventos tras la acción. Un módulo captó estos eventos y, en un temporizador, los incluyó en 'llamadas API' (para la eficiencia de la red).

El resultado fue un sistema central completamente RESTful. El segundo resultado fue que tenía una interfaz para terceros, que podía exponer usando perfiles de afiliación según el modelo de negocio.


-1

Una ventaja es que se verá obligado a pensar en el flujo de la interfaz de usuario desde la perspectiva del usuario. (¿Qué estoy tratando de lograr? ¿Qué contexto necesito establecer? Dado ese contexto, ¿cómo puedo lograr el objetivo?)

Hay una gran diferencia entre "crear cuenta bancaria" y "escribir documento de Word ms". Incluso si no crea una CLI, puede agregar valor solo para considerar el "contexto de CLI" necesario. ¡Los modelos no solo viven en el modelo de objeto de negocio!

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.