Ahora tengo algunos grandes productos multiinquilinos basados en la web, y muy pronto puedo ver que habrá muchas personalizaciones que son específicas del inquilino.
Un campo adicional aquí o allá, tal vez una página adicional o alguna lógica adicional en medio de un flujo de trabajo, ese tipo de cosas.
Algunas de estas personalizaciones pueden integrarse en el producto principal, y eso es genial. Algunos de ellos son altamente específicos y se interpondrían en el camino de todos los demás.
Tengo algunas ideas en mente para manejar esto, pero ninguna de ellas parece escalar bien. La solución obvia es introducir un montón de configuraciones a nivel de cliente, permitiendo que se habiliten varias 'características' por cliente. La desventaja con eso, por supuesto, es la complejidad y el desorden masivo. Podría introducir una cantidad realmente enorme de configuraciones y, con el tiempo, varios tipos de lógica (presentación, negocios) podrían salirse de control. Luego está el problema de los campos específicos del cliente, que pide algo más limpio que simplemente agregar un montón de campos anulables a las tablas existentes.
Entonces, ¿qué están haciendo las personas para gestionar esto? Force.com parece ser el maestro de la extensibilidad; obviamente, han creado una plataforma desde cero que es súper extensible. Puede agregar a casi cualquier cosa con su interfaz de usuario basada en web. FogBugz hizo algo similar cuando crearon un robusto modelo de complemento que, pensándolo bien, podría haber sido inspirado por Force. Sé que gastaron mucho tiempo y dinero en ello y, si no me equivoco, la intención era usarlo internamente para el desarrollo futuro de productos.
Suena como el tipo de cosas que podría tener la tentación de construir, pero probablemente no debería. :)
¿Es una inversión masiva en arquitectura conectable el único camino a seguir? ¿Cómo maneja estos problemas y qué tipo de resultados está viendo?
EDITAR: Parece que FogBugz manejó el problema construyendo una plataforma bastante robusta y luego usándola para armar sus pantallas. Para extenderlo, crea una DLL que contiene clases que implementan interfaces como ISearchScreenGridColumn, y que se convierte en un módulo. Estoy seguro de que fue tremendamente costoso construirlo teniendo en cuenta que tienen una gran cantidad de desarrolladores y trabajaron en él durante meses, además su área de superficie es quizás el 5% del tamaño de mi aplicación.
En este momento me pregunto seriamente si Force.com es la forma correcta de manejar esto. Y soy un chico de ASP.Net duro, así que esta es una posición extraña para encontrarme.
fuente
Respuestas:
Me enfrenté a un problema similar, y te diré cómo lo resolví.
En primer lugar, hay una biblioteca "central" o motor. Básicamente, esto ejecuta el programa, tal como ya lo has descubierto. Maneja cosas comunes a todos los sistemas, desde la representación dinámica de formularios, la administración de usuarios y cuentas, roles, lo que sea, lo hace.
Cada parte del sistema está contenida dentro de un módulo. Un módulo tiene dependencias (otros módulos de los que depende). Por ejemplo, el sistema "central" tiene Seguridad (usuarios, grupos, roles, políticas de contraseña), Configuración regional (traducciones, países, culturas), Depósito de archivos, Correo electrónico, etc. Cada módulo se define a sí mismo usando un archivo xml. El archivo xml básicamente especifica los esquemas, tablas, clases de cálculo, definiciones de pantalla, etc. Estos se leen cuando se inicia la aplicación si la fecha del archivo ha cambiado .
Los módulos específicos del cliente tienen sus propios archivos xml y su propia DLL. Todo se suma y funciona en consecuencia y de forma transparente con el resto del sistema. Hasta reemplazar las vistas MVC existentes por otras personalizadas, con código personalizado y modelos de vista personalizados.
Si un cliente desea ampliar la funcionalidad existente, el xml / system proporciona un método en el que puedo "derivar" un módulo de otro. El nuevo módulo tiene toda la funcionalidad existente, pero con los requisitos específicos del cliente en una nueva DLL y con un archivo XML extendido que puede realizar las modificaciones. La advertencia es que, en realidad, no pueden eliminar los campos existentes en este sistema, pero podemos extenderlo y proporcionar objetos y funcionalidades completamente nuevos.
fuente
Tener mucha lógica de control de versiones y capas de código para administrar no agrega valor a su aplicación / sitio web. También requiere más poder mental para comprender lo que está sucediendo y te distrae del núcleo de lo que estás haciendo.
Aconsejo de otra manera. Aconsejo mantener las cosas simples sobre complejas.
Mantenga una base de código único que sea igual para todos. Cada característica que agregue es una característica para todos. Solo restrinja el número de artículos o almacenamiento o alguna cosa cuantificable, no características. La razón es que cuantificar cosas como el almacenamiento, la cantidad de entradas de datos, etc. es tan simple de programar y se puede aplicar a solo un pequeño puñado de cosas que realmente restringe al usuario de volverse loco en su aplicación. Solo necesita ser programado al agregar elementos en lugar de hacer alguna lógica de características. ¿Qué pasa si las características están vinculadas a otras características? Se vuelve muy complicado codificar para esto.
Para calificar mi respuesta, he creado un marco de comercio electrónico que tengo para muchos clientes y he aprendido la forma difícil de tratar de mantener todas sus idiosincrasias. Terminé rompiendo la cadena y creé un sitio web de administración único que es multi-tennant para el comercio electrónico. Luego tengo sitios web que extraen datos de llamadas de servicio web. Esto permite que diferentes equipos en diferentes tecnologías implementen características específicas para sitios de comercio electrónico mientras sigo cobrando cada mes en la misma infraestructura y no me importa lo que estén haciendo. Solo limito el uso por números, no por características. Es mucho más fácil. El cliente puede elegir su propio proveedor para construir su sitio web y ya no estoy involucrado en esas decisiones.
También tengo un servicio de suscripción para la gestión de contenidos SAAS. Esto también funciona por niveles de uso y los clientes pueden agregar sus propios complementos si lo desean, mientras que mi equipo agrega más funciones para todos.
Esta es solo mi experiencia al golpear mi cabeza contra la pared después de tanto tiempo, y luego tropezar con algo más simple.
Si algo siempre va a ser específico para cada cliente, no cree un marco para ello. Divídalo en sus partes más simples para que la parte del marco funcione para todos y luego corte el resto para que pueda extenderlo para el individuo.
fuente
El producto de software en el que trabajo tiene campos adicionales para la extensibilidad del usuario. Cada elemento de datos para estos campos se puede asignar a una fila existente en las tablas principales de la aplicación. Por ejemplo, si su software contiene clientes y cada cliente una lista de pedidos, la tabla de datos personalizables tendrá una columna para las claves externas de la tabla de clientes y la tabla de pedidos, de los cuales solo uno no será nulo. O eso o varias tablas, cada una con los campos personalizados para una tabla.
Esta es una forma simple y eficaz de almacenar datos adicionales para el usuario. Debería almacenarse información adicional sobre los nombres y tipos de estos campos.
Eso cubre los campos personalizados para un cliente. Para un comportamiento personalizado, una API de servicios web permitiría extensiones.
fuente
1) Ejecutar el código de otra persona en cajas de su propiedad es un problema bastante difícil. O puede confiar en ellos o puede diferir la responsabilidad razonablemente, tendrá que proteger mucho su código y tener una dedicación a la seguridad superior a la media. A medida que su sistema de complementos permite una mayor funcionalidad, aumenta la dificultad de hacerlo seguro. Cosas como la denegación de servicio (los complementos consumen demasiados recursos), la fuga de información (los complementos pueden acceder a los datos de otros inquilinos), etc. pueden ser muy reales y problemáticos, no tomaría parte en esto a menos que pudiera familiarizar a las personas estos problemas o personas muy capaces con mucho tiempo para hacerlo bien.
2) Sí, la modularidad y la personalización son difíciles. Cosas como el patrón de estrategia pueden ayudar (un nombre elegante para punteros de función; en Java generalmente se implementa al declarar una interfaz que los usuarios de la clase pueden implementar para personalizar el comportamiento de su código), pero querrá estar muy aislado y desacoplado código para que esto funcione.
3) En cuanto a los datos, este podría ser uno de los ejemplos de almacenamiento sin esquema que sea útil. Si tiene un modelo de datos relacionales, tener tablas con muchas columnas para diferentes clientes es problemático (sí, termina con muchas columnas anulables, lo cual es malo ; una razón es que es difícil o imposible establecer las restricciones correctas [es decir restricciones que no permiten que aparezcan combinaciones inválidas de nulos]). Adición de tablas específicas de cliente (es decir,
users
yfoo_users
, conusers
la celebración de los campos válidos para todos los clientes yfoo_users
que tiene los campos campos específicos Foo) es mejor; puede tener restricciones correctas fácilmente, pero es posible que su RDBMS no lo maneje con gracia (debido a una explosión de unión, límites en el número de tablas, etc.) y probablemente se verá feo en su código.Puede terminar implementando un almacén de valores clave en su RDBMS, lo que hace que su modelo de datos sea menos relacional y causará molestias (es decir, las bases de datos relacionales funcionan mejor con modelos relacionales). No estoy seguro de si una solución NoSQL se ajustará al problema en general, pero la falta de esquemas de la mayoría de las implementaciones podría ser una ventaja.
fuente