Organizar aplicaciones de nivel empresarial

La organización puede hacer o deshacer la mantenibilidad de una aplicación. Con aplicaciones más pequeñas, la organización es más evidente; sin embargo, a medida que la aplicación crece y el número de desarrolladores de aplicaciones e ingenieros de front-end que producen el código aumenta, la organización se vuelve más confusa. En esta publicación, repasaremos algunos conceptos básicos para mantener las aplicaciones organizadas de modo que encontrar un código relevante sea un proceso eficiente y sistemático..


Aprender de los marcos

JavaScript debe estar dentro del alcance de una manera eficiente.

Tomemos un momento y consideremos la forma en que los equipos de Rails y Wordpress organizan sus proyectos. Es probable que haya trabajado con uno u otro de estos. Ambos marcos tienen una estructura por defecto establecida.

Al generar una aplicación de Rails, Rails maneja gran parte de las necesidades organizativas principales para usted. Debido a que se basa en MVC, la configuración predeterminada de Rails incluye una carpeta con la etiqueta "app", que contiene las carpetas modelo / vista / controlador. También proporciona los "ayudantes" y los "correos", las extensiones de controlador que ayudan a llenar los huecos entre los controladores y los modelos..

Rails también genera algunos otros elementos al mismo nivel que la carpeta "app", como configuración, registro, bases de datos, almacenamiento temporal / caché, pruebas y algunas otras piezas. Lo que es particularmente interesante para esta discusión son la aplicación y las carpetas públicas. La carpeta pública es desde donde se sirven los activos estáticos, incluidos los archivos HTML, CSS y JavaScript no dinámicos..

Cuando se trabaja con Wordpress, la denominación y la estructura son mucho menos obvias..

... la aplicación está diseñada para los usuarios ...

Los convenios se exponen a través de la documentación. En particular, es probable que los desarrolladores trabajen dentro de un tema, ubicado en el directorio wp-content / themes /. Este tema tiene una serie de archivos con nombres especiales, principalmente basados ​​en vistas. UNA funciones.php El archivo actúa como un "controlador" de tipo, donde un desarrollador puede poner funciones para separarlas de las vistas. Sin embargo, los temas de Wordpress a menudo enturbian las aguas entre la lógica y la presentación. Por ejemplo, las consultas de la base de datos están implícitas por el nombre de archivo, pero a menudo se manipulan modificando la consulta antes de recorrer los resultados devueltos. Esta manipulación no se abstrae de la misma manera que lo haría un controlador (y, por supuesto, Wordpress no se encuentra cerca de MVC, por lo que no podemos esperar este tipo de organización).

Ambos marcos son extremadamente populares, y ambos usan su propia estructuración implícita. Requieren absolutamente que los desarrolladores entiendan cómo funciona el sistema para ser eficiente. En nuestras propias aplicaciones, debemos prestar atención a este paradigma organizativo y crear un enfoque sistemático para estructurar las aplicaciones. Esto se realiza de manera muy diferente para cada aplicación individual..


Construyendo un estándar

Los marcos mencionados anteriormente no requieren que los desarrolladores definan la estructura; Están "pre-cableados" para trabajar de una manera específica..

Una razón importante por la que los marcos sólidos a menudo abstraen estas configuraciones y proporcionan estructuras predeterminadas es para que las personas comiencen a desarrollar un estándar de comunidad basado en la estructura predeterminada.

No ignore los estándares al organizar su aplicación.!

Si está familiarizado con Rails, lo más probable es que pueda ver un repositorio de Github y saber si es una aplicación de Rails solo por la estructura de carpetas. Rails tiene un estándar documentado..

¡No ignore los estándares al organizar su aplicación! Es muy probable que si está organizando una aplicación de nivel empresarial, esté tratando con miniaplicaciones modulares basadas en servicios discretos. Por ejemplo, puede darse el caso de que tenga varias aplicaciones creadas con uno o más marcos diferentes, o se puedan rodar a mano y trabajar en conjunto unas con otras, exponiendo las API que proporcionan enlaces para los otros servicios. Es probable que cada una de estas aplicaciones discretas siga los estándares del marco en el que se construyó; Estas normas existen porque son la forma en que este marco fue diseñado para funcionar. Si intenta cambiar estos estándares dentro de una aplicación discreta, es probable que termine perder más tiempo configurando que en realidad la construcción de una aplicación de trabajo.


Uniformidad de las piezas conectadas, singularidad de las piezas discretas

En la práctica, esto significa que las cosas que están expuestas de un servicio a otro deberían funcionar de manera uniforme, y las piezas que son internas a un servicio deberían funcionar de la mejor manera para ese servicio en particular, probablemente impulsadas por cualquier marco o estructura. pila de tecnología que el servicio se ejecuta en.

Recuerde, al final del día, la aplicación está diseñada para los usuarios, y los usuarios no saben ni aprecian la separación de los servicios discretos.

En cambio, entienden la aplicación y la experiencia como una sola pieza, y esa pieza se beneficiará principalmente de la uniformidad en el nivel superior.

Entonces, ¿qué necesita ser uniforme?

Rutas

a medida que la aplicación crece ... la organización más confusa puede volverse.

Las rutas (estructuras de URL) son uno de los factores definitorios más importantes de cómo funciona una aplicación web. Es importante que tus rutas sigan una estructura uniforme. Por ejemplo, cuando se muestra una "cuenta de usuario" con una URL como / usuario / 5 dónde 5 es el ID de entero de clave primaria del usuario, no debe usar un plural para otro objeto singular, como / widgets / 16. En su lugar, debería ser / widget / 16. Esto no solo ayuda a los desarrolladores al ser coherentes, sino que también proporciona claridad y uniformidad para los usuarios. No importa lo que elija para la estructura de su ruta siempre y cuando sea coherente en el nivel de orientación al usuario..

Sintaxis API

Este es uno de los más importantes para el desarrollo interno, y aún más importante para el desarrollo de productos / servicios de software donde una API está expuesta al público. Si sus llamadas a la API tienen caracteres de subrayado como separadores de palabras, no use una clave camelCase o un guión separado en su API en otra parte. Si usa la palabra "contar" para significar "devolver este número de objetos", no use algo como "cuenta_per_página" para significar lo mismo en otras partes de la misma API (o una relacionada). Este es un diseño API descuidado. Desarrolla una sintaxis estándar y apégate a ella; Tenga en cuenta que a menudo esto se resuelve con un diseño de ruta bien ejecutado en las API REST..

Nombres, verbos y etiquetas

En un nivel general, al tratar con "foo widgets" (objetos o acciones arbitrarios) dentro de su aplicación, asegúrese de utilizar la misma terminología en todas sus aplicaciones. Por ejemplo, aunque puede ser una práctica común en Rails usar el directorio "público", usted tiene control sobre lo que va dentro de él..

No utilice una carpeta "js" para un marco y una carpeta "scripts" para otro marco.

No llame a los modelos de datos "orange_items" en un marco y a "OrangeItems" en otro, a menos que el lenguaje o el marco lo requiera explícitamente por una razón funcional. Incluso entonces, asegúrese de que haya un sistema y una "gramática" consistentes, y asegúrese de que las diferencias entre los servicios discretos sean bien documentado y justificado. Este tipo de señales y uniformidad ayudarán en gran medida a comprender las clasificaciones de objetos en una aplicación..

Rutas espejo, carpetas y archivos estáticos

La duplicación de rutas a carpetas y archivos ayuda en gran medida a mantener una aplicación organizada. Por ejemplo, puede tener carpetas para CSS, JavaScript e imágenes dentro de sus carpetas "públicas" o "estáticas". Crear una estructura de carpetas que se asigne a sus rutas, vistas, controladores u otras estructuras similares puede ayudar a mantener su CSS modularizado. Luego puede usar una herramienta como CodeKit para concatenar estos archivos en un único archivo minificado. Por supuesto, también puede tener un global.css Para las reglas que se aplican en toda la aplicación. Vea a continuación un ejemplo (.rb es para Ruby, pero esto podría ir para cualquier organización marco de MVC).

- root / - app / --- models / ---- foo.rb ---- bar.rb ---- baz / ----- widget.rb --- views / ---- global. html.erb ---- foo.html.erb ---- bar.html.erb ---- baz / ----- widget.html.erb --- controladores ---- foo.rb - - bar.rb - public - CSS --- global.css --- foo.css --- bar.css --- baz / ---- widget.css - JS --- global.js - - foo.js --- bar.js --- baz / ---- widget.js - Images / --- global / ---- image.jpeg --- foo ---- image.jpeg --- barra ---- imagen.jpeg --- baz / ---- widget / ----- imagen.jpeg

Uno puede ver rápidamente que no sería difícil encontrar CSS, JavaScript, modelos, etc. específicos para una sección específica de la aplicación.

Las rutas (estructuras de URL) son uno de los factores definitorios más importantes de cómo funciona una aplicación web.

La mejor manera de pensar esto es separar sus archivos en "áreas" de su sitio. Por ejemplo, quizás tenga una aplicación que incluya un área de "administrador" y un área de "perfil". Podrías crear un global.css el archivo para contener los objetos / reglas que se aplican a ambas áreas (incluido un restablecimiento, algunas reglas de tipografía, colores, etc.) y luego crea archivos específicos que se aplican a áreas separadas para las reglas de estilo de contenido que no se comparten. De esta manera, como un desarrollador trabaja en una página específica, permanecerán en uno o dos archivos y sabrán exactamente dónde encontrar los archivos correctos..

... o, nombre sus archivos estáticos por su función

Otra forma efectiva de controlar sus archivos estáticos es nombrarlos en función de lo que hacen. Por ejemplo, crear un reset.css, una typography.css, una dimensiones.css, una colores.css, Este método tiene ventajas y desventajas, particularmente para CSS. Mantiene su CSS enfocado en las reglas de presentación; sin embargo, es probable que requiera que repita los selectores en varios archivos, volviéndolos a abrir para definir diferentes tipos de reglas de estilo. La única forma de evitar esto es nombrar sus clases / ID solo por estilo en lugar de semántica, como class = "texto verde de cinco columnas de media sombra". De lo contrario, terminarás haciendo algo como esto:

En typography.css

.widget semántico color: # 232323; text-shadow: 1px 1px #fff; tamaño de letra: 1.2em; altura de la línea: 1.1em; Familia tipográfica: sans-serif; peso de la fuente: 300; 

En dimensiones.css

.widget semántico ancho: 20%; margen: 0 2.5%; relleno: 10px; 

Lo que por supuesto no es tan SECO como sea posible.

La organización de aplicaciones más pequeñas (con menos de estos objetos "widgets") aún puede beneficiarse de la separación por tipo de regla.

Sin embargo, si tiene una aplicación que tiene muchos tipos de objetos, áreas de aplicación, etc., probablemente deba elegir separar sus archivos CSS en áreas (la estrategia de creación de reflejo que analizamos anteriormente).

Nombrar archivos JavaScript por sus funciones es un poco más factible, pero solo si está aprovechando los disparadores de eventos (un modelo de publicación / sub). Considere el siguiente ejemplo:

$ .getJSON ("/ messages / all.json", function (data) // hacer algunas cosas);

Es posible que desee hacer bastantes cosas en esta devolución de llamada. Es posible que desee enviar una notificación al usuario y actualizar una lista de mensajes. Si tiene sus archivos separados por funcionalidad, puede tener un notificaciones.js y un mensajes.js Archivo que maneja estas funciones particulares. Dentro de la devolución de llamada para esta llamada ajax JSON, debería "publicar" un evento para el resto de la aplicación. Luego, dentro de sus notificaciones y archivos de mensajes, puede "suscribirse" al evento y responder en consecuencia.

en eventos.js:

$ .getJSON ("/ messages / all.json", función (mensajes) $ ("cuerpo"). disparador ("mensajes recibidos", mensajes););

en mensajes.js:

$ ("cuerpo"). en ("mensajes_cibidos recibidos", función (evento, mensajes) // iterar a través de mensajes y adjuntarlos a una lista);

en notificaciones.js

$ ("body"). on ("recibido_mensajes", función (evento, mensajes) // send_notification puede ser una función local que le permite enviar notificaciones // al usuario, junto con un tipo de notificación, un entero; por ejemplo, en este // caso, "1" puede significar simplemente diseñar la notificación como una alerta de "éxito" send_notification ("¡Mensajes recibidos con éxito!", 1););

Otra nota sobre archivos estáticos

Hay algunas cosas que debes tener en cuenta acerca de tus archivos estáticos. Este artículo asume que usted concatenará sus archivos estáticos de una manera apropiada. Pero que es exactamente lo apropiado?

Considerar la complejidad del sitio

Chris Coyier recientemente Afirmó que ninguna aplicación necesita más de tres archivos CSS. En un formato destilado, afirma que la mayoría de los sitios que tienen una página, o muchas páginas que son muy similares, necesitan un archivo CSS. Las aplicaciones que tienen diferentes secciones "aisladas" necesitan un archivo CSS para elementos globales y un archivo para las secciones específicas. Finalmente, los sitios muy complejos necesitan tres archivos (css global, de sección específica y de página única). Chris se refiere a los archivos que se cargan en la cabeza (no necesariamente en lo que desarrollas), por lo que estos serían tus archivos concatenados..

Entonces, ¿por qué harías esto, preguntas? Principalmente para aprovechar el caché del navegador..

La concatenación sobre la marcha, por ejemplo, no le permite aprovechar la memoria caché del navegador. La otra ventaja de este enfoque es que solo carga lo que necesita. Si tiene una sección completa de "admin" que el 95% de sus usuarios nunca ve, no deberían tener que descargar el CSS para esa sección.

Desarrolla una sintaxis estándar y apégate a ella.

Al igual que en CSS, JavaScript debe tener un alcance eficiente.

Las ganancias siempre deben ser manejadas con cuidado; Si su javascript es lo suficientemente pequeño como para justificar la concatenación en un solo script, no se sienta presionado a cargar JavaScript modular en su producto final..

Considerar el volumen de uso

Como se mencionó brevemente anteriormente, si hay una cantidad insignificante de usuarios que llegan a una página específica, no coloque el CSS / JS en los archivos estáticos de su aplicación global. Los archivos estáticos administrativos también deben permanecer separados. Si su aplicación admite cuentas de usuario, considere la posibilidad de excluir los archivos estáticos del lado no autorizado (marketing) de la aplicación. Una vez que un usuario inicia sesión, ya se ha comprometido a participar en lo que sea que su aplicación proporcione. Las primeras impresiones lo son todo, y cargar un montón de CSS y JavaScript no utilizados solo degradará el rendimiento de una primera impresión.


Lo que debería ser único?

Si de hecho está utilizando un marco, use la estructura existente de ese marco. Si su marco no tiene una estructura existente, o una estructura muy simple (Sinatra y CodeIgniter son excelentes ejemplos de esto), considere duplicar la estructura de otros componentes en la aplicación. Si está comenzando desde cero, eche un vistazo a otros proyectos que la gente ha completado tanto en el marco que está utilizando como en otros que usan el mismo idioma. Por ejemplo, si eliges el framework, funciona en MVC pero no tiene configuraciones predeterminadas para la colocación de estas piezas, es probable que haya un nombre convención que utiliza las palabras clave Modelo, Vista y Controlador.

Cuando se trata de eso, la organización de nivel empresarial se basa en cuatro cosas principales:

  1. Se consistente; Desarrollar convenciones internas de toda la aplicación..
  2. Seguir las convenciones marco / comunidad cuando sea posible y cuando sea necesario..
  3. Hacer elecciones lógicas, auto-documentadas.
  4. Documente sus elecciones y asegúrese de que las inconsistencias dentro del sistema o con las convenciones sean expuestas y conocidas por todos los que trabajan en el software..