¿Por qué se considera una mejor práctica empaquetar el código del programa y el código de la interfaz gráfica en diferentes clases?

15

Entonces mi maestro me dice que es muy importante no encapsular el código del programa y el código de la interfaz gráfica en las mismas clases, sino mantenerlos completamente independientes. Actualmente estoy escribiendo un juego para iPhone con una cuadrícula. para mí tiene mucho más sentido crear tanto la cuadrícula gráfica como el código técnico en la misma clase de "cuadrícula". ¿Otro programador desaprobará esto? ¿Es realmente muy importante mantener la interfaz gráfica y el código independientes? ¿Qué problemas surgirán si no lo hago?

¡Gracias!

EDITAR: gracias chicos! ¿Estaría bien para mí escribir primero el proyecto y luego copiar el código para formar el diseño de separación de preocupaciones? Sé que esto puede derrotar totalmente el propósito, pero solo como práctica ... ¿Para que la próxima vez pueda aplicar este patrón de diseño desde el principio?

John
fuente

Respuestas:

17

El concepto al que se refiere su maestro es algo llamado Separación de preocupaciones.

Para ilustrarlo en su contexto, si completa su programa y luego decide que desea portarlo a Android; Tendrá que volver a escribir mucho más código que si hubiera mantenido la lógica de la cuadrícula separada.

Un control de interfaz solo debe preocuparse por dibujar lo que se dice, la lógica de la cuadrícula solo debe preocuparse por lo que está en la cuadrícula, no por cómo dibujarlo.

¿Esto ayuda?

Russ Clarke
fuente
Gracias, ayudó. La cuestión es que es mucho más fácil para mí visualizar mi producto final cuando encapsulo ambos en una clase. ¿Es esta una razón válida para no seguir la "separación de preocupaciones"? ¿O es absolutamente necesario y no podría llamarme un programador adecuado: p?
Un efecto positivo de esta separación es que no tienes que reescribir la lógica de tu juego, si eliges reemplazar tu interfaz gráfica de usuario, por ejemplo
@John: escriba un documento de especificación si necesita visualizar su diseño. Si puede describirlo, puede comenzar a separar el código de la interfaz gráfica de la lógica del juego.
Ramhound
3
También hace que el código de cuadrícula sea más fácil de probar. Probar las GUI es doloroso (debido a posibles problemas de confusión de los entornos), por lo que lograr que la GUI sea una capa delgada "obviamente correcta" sobre algo que es comprobable es una gran victoria. (Nuevamente, esto es Separación de preocupaciones.)
Donal Fellows
1
@ John: Algunos de nosotros aprendemos mejor haciendo. Suponiendo que este proyecto no sea tan grande, intente escribirlo como una sola clase y haga que funcione en el iPhone. Ahora transfiéralo a Android, manteniendo un registro de sus "puntos débiles". Finalmente, reescríbalo como lo sugirió Russ C. Creo que verá por qué la separación de la lógica y la presentación es el camino a seguir.
Peter Rowell
4

Para que sea más fácil cambiar su código . ¿Qué pasa si mañana no quieres usar una cuadrícula sino una lista? Cuando su GUI está separada de su lógica, es fácil de hacer.

Además de eso, escribirás código que sea más reutilizable . Si su GUI no contiene su código técnico, también puede reutilizarlo. Cree una grilla elegante con todas las opciones una vez y puede usarla en otros proyectos. Mezclar su GUI y su código técnico le impedirá hacerlo.

También le da un código que es más fácil de leer. Si su grilla solo hace la funcionalidad de la GUI, es más fácil de entender o cambiar su código.

Carra
fuente
3

El enfoque general de la programación orientada a objetos a una separación de preocupaciones , donde el código se separa en tareas lógicas. Inicialmente, esto puede parecer más trabajo. Pero a medida que su proyecto crece, hace que sea más fácil rastrear y administrar su código.

Por esa razón, probablemente sería mejor separar el código responsable de mostrar una cuadrícula y el código que se ocupa de los datos que se pueden mostrar en esa cuadrícula.

Jonathan Wood
fuente
0

Para construir sobre las otras respuestas y darle un ejemplo, de alguna manera debería permitirse inyectar su lógica / datos en su grilla o viceversa.

Su control de cuadrícula puede exponer un Rendermétodo o un DataBindmétodo.

class GridControl
{
    public Render(GridData data) { ... }
}

o

class GridControl
{
    public DataBind(GridData data) { ... }
}

Luego, su unidad lógica puede tomar el GridControl y vincular un objeto de datos o llamar manualmente a render con el objeto de datos cada vez que algo cambie.

Su GridLogic también debe tener una referencia al GridControl para que pueda unirse a cualquier entrada / evento que ocurra.

La idea detrás del enlace de datos es que su control de cuadrícula vigila los datos en busca de cambios y se renderiza a sí mismo, mientras que al exponer una función de renderizado significa que su unidad lógica renderiza manualmente el control.

De cualquier manera, dividir su lógica y cuadrícula de esta manera le permite cambiar más fácilmente una de la otra sin romper nada. También puede escribir un nuevo control como a ListControlpara mostrar sus datos como una lista en lugar de una cuadrícula sin tener que reescribir toda su lógica.

Raynos
fuente
0

Le recomiendo que eche un vistazo a la arquitectura MVC .

Es un refinamiento del concepto que ha mencionado (separación del código del programa y la interfaz gráfica). MVC significa Modelo-Vista-Controlador. Aquí el Modelo son los datos, Ver es el código de la interfaz gráfica y COntroller es el código que procesa los datos.

De esta manera, ha creado tres partes de su programa. Cada parte se puede reemplazar sin requerir cambios en las otras dos partes.

DPD
fuente
0

Depende de los tipos de cambios futuros que puede esperar que ocurran. Lo que desea minimizar es la cantidad de cambios manuales en el código necesarios para implementar correctamente cada cambio funcional.

Donde MVC gana es si los cambios se limitan a la parte V, o "Ver".

En mi experiencia, es mucho más probable que los cambios afectan a las tres partes, por lo que es mejor si son no separados. Para mostrar lo que quiero decir, he usado durante mucho tiempo una técnica que desarrollé llamada cuadros de diálogo dinámicos , en la que un nuevo requisito, como "permitir que el usuario edite el nombre, y cuando se completa hacer XYZ" se ingresa en el código fuente como un solo bloque de texto:

if(deTextEdit(&sName)){
  // do XYZ
}

en lugar de múltiples ediciones separadas, para especificar que existe el campo de edición, para crear un identificador único para él, para vincularlo a la variable del modelo y vincularlo al controlador de eventos de foco perdido.

Si va a ese enlace, verá un ejemplo más complejo.

Básicamente, la idea es convertir el código en un lenguaje específico de dominio, a fin de minimizar el número de ediciones para lograr el propósito. La razón por la que desea hacerlo no es solo para reducir el esfuerzo, sino para reducir la oportunidad de introducir errores, olvidando o codificando erróneamente una o más de las ediciones. También reduce el tamaño del código fuente en aproximadamente un orden de magnitud.

No es gratis Introduce una curva de aprendizaje única para el programador.

Mike Dunlavey
fuente
0

La interfaz gráfica depende del sistema, mientras que el núcleo del juego es un algoritmo totalmente independiente del sistema en el que se ejecuta. Mantener los dos apartados hará que el programa sea más fácil de mantener, probar y depurar porque los cambios en un subsistema no afectan la forma en que funciona el otro. Incluso si no le importa la portabilidad, apuesto a que le importa la robustez y la capacidad de mantenimiento de su programa.

Gus
fuente