¿Cómo puedo planear mi software para evitar la reescritura y las interdependencias excesiva

StackOverflow https://stackoverflow.com/questions/3472405

  •  28-09-2019
  •  | 
  •  

Pregunta

Estoy escribiendo un controlador de motor que tiene un par de interfaces (botones, Bluetooth, mandos táctiles) que es una tarea que está en constante crecimiento a ser un grande de lo que imaginé. He tratado de ir en ella, empezando con módulos de bajo nivel (por ejemplo, código de escritura para hablar en el bus I2C), y luego los de arriba que (código para hablar con un dispositivo en particular en el I2C bus ...), pero con demasiada frecuencia tengo que vuelve a bucear hasta mis módulos inferiores de manejar peculiaridades que no cabida. Esto tampoco lleva mucho tiempo o que realmente obtener el código hack-ish.

Mi destino es una de 8 bits MCU, por lo que de abajo hacia arriba parece como si pudiera explotar el hardware mejor. Si ir de arriba hacia abajo no tengo ninguna estructura para construir o de prueba / depuración.

he intentado elaborar algunos esquemas generales y los particulares de niveles / conductores, pero no estoy seguro de cómo estructurar ellos, así que puede ser muy sistemática al respecto y evitar la pérdida de la señal extraño que tiene que ir a través de 2-3 capas.

Creo que esta es la razón de un grado CS? Soy un ingeniero eléctrico: P

¿Fue útil?

Solución

Parece que usted está en el camino correcto. A veces, ninguna cantidad de planificación va a evitar que tener que rediseñar o partes Refactor de un sistema en una fecha posterior. Pruebe algunos de los siguientes consejos:

  • Mantenga su código en módulos separados por funciones lógicas.
  • Do código no duplicado, en lugar diseñar métodos reutilizables para la funcionalidad compartida.
  • Trate de evitar la tentación de añadir hacks para casos especiales. Con el tiempo esto se convertirá en imposible de mantener. En su lugar, ajustar y refactorizar pequeñas secciones tan pronto como sea posible. Tratando de hacer un gran rediseño al final va a ser más difícil.
  • No trate de sobre-diseñar el sistema desde el principio, ya que sólo podría estar perdiendo su tiempo cuando se llega a la implementación real.
  • Mantenga los niveles más bajos tan simple como sea posible, a continuación, construir capacidades más avanzadas en la parte superior.
  • Documentar sus funciones y escribir algunas pruebas unitarias, especialmente después de la adición de sentencias condicionales complejas.
  • Trate de detectar los errores lo más alto de la pila como sea posible. Por ejemplo hacer la validación de entrada y comprobación de los valores de retorno. Esto hará más fácil la depuración.

Otros consejos

Cuando se trabaja en el código de múltiples niveles, es tentador sumergirse en un nivel más bajo cuando la API no le permite hacer exactamente lo que quiere que haga. Esto es especialmente difícil cuando escritura niveles mulitple al mismo tiempo.

Aquí hay algunas sugerencias:

  • Tratar a todos los demás niveles que la que se está trabajando en como si ellos están sellados. Creado por otra empresa, desarrollador, etc. Resiste la tentación de modificar otro nivel para resolver un problema en su nivel actual.
  • Crear una lista "hermanos" a la que se está trabajando. Esto es difícil de describir en sentido abstracto, pero digamos que el nivel inferior es una capa de negocio, y el nivel superior es una interfaz de usuario, crear otra capa de interfaz de usuario para una aplicación diferente. Ahora que tiene dos consumidores del punto puede ayudar misma API a cabo lo que debería ser en cada capa.
  • Trate de alternar el orden en que se trabaja en gradas. Por ejemplo, en algunas aplicaciones me resulta más útil para diseñar la interfaz de usuario primero, y luego trabajar mi camino hacia abajo a la capa de negocio / base de datos para hacer que el trabajo de interfaz de usuario como se ha diseñado. Otras veces, tiene más sentido a stat con el modelo de datos y el trabajo hasta una interfaz de usuario. Pero el punto es, que "piensa" de una API diferente en estos dos escenarios. Y habiendo mirado código de varios niveles desde ambos ángulos de ayuda.
  • La experiencia cuenta. A veces, sólo en el error de código excesivamente acoplado es la única manera de aprender realmente a evitarlo. En lugar de planear en su aplicación es perfecta, al estar sobre el mismo plan de imperfecto. Con esto quiero decir estableció por primera vez un ciclo de desarrollo / prueba / refactor rápida, de manera que pueda adaptarse rápidamente a los errores que usted no ve hasta después de haberlos hecho. Esto también es un área en la que "usar y tirar prototipos" viene muy bien. Hacer un simple borrador, aprender de ella, y tirarlo a la basura. La parte del tiro lejos es importante. Incluso si su sorprendente, empezar a construir otra desde cero. Se quiere inevitable que sea mejor (y en mi Expirience, más organizada) en base a lo que ha aprendido a partir del prototipo.

Es realmente más una cuestión de experiencia que no sea su grado. Si todavía está aprendiendo cosas acerca de cómo controlar el hardware, entonces, por supuesto, el código va a cambiar. No me cuesta trabajo que eso. Sin embargo, ya que lo que está haciendo en realidad es la creación de prototipos, debe estar listo para refactorizar el código una vez que tenga que trabajar. Retire las redundancias de datos, compartimentar y funcionalidad, y organizar sus interfaces de modo que tiene sentido.

Mi experiencia es que el código de controlador de dispositivo necesita de arriba hacia abajo y el diseño / implementación de abajo hacia arriba, lo que yo llamo de afuera hacia adentro. Ya sabes lo que el usuario va a querer hacer y se puede escribir esas interfaces, y usted sabe lo que el conductor de bajo nivel que tiene que hacer y que se escribe. Si no cumplen bien en el medio, reflexionar sobre el diseño del módulo.

Para la mejora, sin perjuicio de su diseño y el código a revisión por las personas con más experiencia. Dejar de lado el ego de ella y acaba de obtener su opinión sobre el problema. También puede leer un libro en el análisis y diseño orientado a objetos (que tenía gusto de los libros de Peter Coad. No sé que les está escribiendo ahora). Una buena mostrará ejemplos de cómo particionar un problema en objetos con funciones y responsabilidades claras.

La otra pieza, una vez que haya terminado de prototipos de los conductores y saber cómo controlar el hardware, es hacer que los requisitos de seguro que usted ha detallado. Nada tuerce código de descubrir más de los requisitos mientras se escribe. También puede intentar aprender UML y el diseño con diagramas antes de escribir código. Esto no funciona para todo el mundo. También tenga en cuenta que no es necesario ser de codificación en un lenguaje que los apoyos orientados a objetos construcciones para uso OOD.

Si su problema es cómo construir abstracciones adecuadas, lo que parece ser el caso, creo que lo más importante que puede hacer para aprender (además de pedir una revisión de diseño de código / leer libros / lectura de código) es que pensar mucho antes de empezar a escribir código .

Suele ocurrir que se inicia con una idea aproximada de lo que quiere y cómo se debe hacer y luego ir a escribir código. Más adelante se descubre que usted no piensa las cosas y tiene varios agujeros que ahora, debido a que han invertido tiempo en escribir el código, son difíciles de parche, lo que conduce a la pérdida de tiempo, ya sea o código hacky.

Piensa bien acerca de cómo crear un diseño que puede manejar fácilmente los cambios. Por ejemplo, encapsular los datos que necesita para viajar entre las capas, por lo que si más adelante descubre se ha perdido un parámetro crucial se puede añadir fácilmente a la estructura sin tener que modificar el código en todas partes.

Trate de "ejecutar el diseño en su cabeza", varias veces, hasta que esté seguro de que reasoanly que se han considerado detalles más importantes y se puede decir (esta es la parte más importante, porque vas a perder las cosas siempre o requisitos cambiará) que si se ha perdido algo que se puede ajustar los módulos con relativa facilidad.

UML puede ayudar a estructurar la manera de pensar en el diseño. Es ciertamente no es la panacea pero muestra los diferentes criterios a tener en cuenta al crear un diseño de software.

Es un poco como el consejo clásico maestro de ajedrez: " se sientan en sus manos ": -)

Controladores son susceptibles de un enfoque de capa.

Los controladores podrían tener varias "clases":

  • Sólo para la entrada
  • única salida
  • tanto I y O.

Se debe tener una interfaz estandarizada, por ejemplo .:

GetKnobLevel()
GetNextKeyboardButton

O, otro enfoque es tener algo así como

syscall(DRIVERNUMBER, command)

poner parámetros / resultados en los registros especificados.

Es un simple enfoque utilizable. Una variante más compleja podría ser tener colas circulares entre su código de comunicación de hardware y software de su código de comunicación, en lugar de registros.

Este es el modelo mental que estoy utilizando:

---
Application
---
OS
---
Driver communicators
---
drivers
---
hardware

Hay una fuerza definida, la interfaz de no-varianza entre cada capa (I sigo imaginando un pastel de capas con glaseado de espesor entre las capas ...). El sistema operativo puede no existir para ti, por supuesto.

Si su MCU es compatible con las interrupciones de software y hardware, como la CPU x86, se puede utilizar para aislar los conductores de los comunicadores los controladores.

Esto es un poco de una solución "overengineery", para ser honesto. Sin embargo, en una situación en la que su complejidad es cada vez significativo, es más fácil tener la ingeniería apretada que tener la ingeniería suelto.

Si usted se está comunicando entre las capas, se puede utilizar una variable global para cada comunicación "canal", y acceder a ella de una manera disciplinada, utilizando sólo las funciones para acceder a él.

Normalmente, usted querrá hacer diseños de papel en algún nivel, algunos trabajos de exploración, y rediseñar antes de que realmente se dispuso a código de su proyecto. Diagramas de flujo y diagramas de bus de transición funcionan bien aquí.

Este es el enfoque que he favorecido en mi trabajo de sistemas embebidos y funciona bien para mí.

También - este espacio del problema no está bien explorado por los programas tradicionales de la informática. Es mucho menos tolerantes que los sistemas operativos web o moderna.

En mi opinión, los aspectos más importantes de código bien architectured son bajo grado de acoplamiento y separación de los efectos secundarios de estado .

También - código es un arte. No creo que se pueda hacer la solución perfecta desde el principio. Esté preparado para cambiar su código a medida que aprende cosas nuevas. De hecho - Asegúrese de que usted abraza cambiarlo auto como parte de su trabajo

.

Para no ser excesiva facilidad, pero una cita de El mes laboral mítico viene a la mente: "Plan de lanzar uno de distancia; se quiere de todos modos"

El corolario de que es "hacer que funcione. Que sea correcto. Que sea rápido."

supongo que esto me hace un defensor de hacer algún diseño por adelantado, pero no conseguir paralizado por ella. No tiene que ser perfecto la primera vez que pasa. Plan para refactorizar. Esperamos que pueda haber escrito cosas de tal manera que usted no está realmente tirando tanto código de distancia, pero la reordenación de las cosas de una manera más agradable.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top