Microsoft Dynamics AX Design Patterns

Dado el tamaño y la inmensa funcionalidad incluida en Microsoft Dynamics AX, parece lógico pensar que se han seguido diferentes patrones de diseño para implementarlo, y en efecto así es.

Conocer y respetar estos patrones de diseño y tambien las buenas practicas es muy importante para mantener un buen nivel en nuestros desarrollos y procurar no “romper” el funcionamiento estándar de la aplicación con nuestras modificaciones, si bien no todos ellos estan completamente documentados, la mayoría se perfeccionan con la experiencia, pero la base se puede aprender mediante la documentación oficial:

Estos patrones no son arbitrarios, como se puede comprobar la mayoría se basan en patrones de diseño mas o menos estándar o al menos comunmente reconocidos como válidos, por ejemplo:

Lo que la documentación de Dynamics AX llama Best Practices for Constructors es una buena práctica inspirada en el patrón Factorías (Factory method patter):

Factory method pattern(imagen de Wikipedia)

Mediante el cual se crea una clase abstracta cuya única misión será construir objetos (de ahí el nombre, factoría) de clases mas especializadas de una clase padre común. Por ejemplo. Si tenemos una clase padre Vehículos y muchas clases hijas Vehículo_Coche, Vehículo_Camión, Vehículo_Moto. Según este patrón la única manera de implementar estas clases hijas será a traves de una nueva clase VehículosFactory, la clase factoría, dedicada a construir instancias del resto de clases específicas.

Dicho así esto parece muy complicado pero no lo es, en el estándar lo vemos en muchos módulos por ejemplo, en las clases SalesEditLinesForm:

Design Patterns | 1

La clase padre SalesEditLinesForm tiene un constructor para las clases específicas:

static SalesEditLinesForm  construct(DocumentStatus  documentStatus, boolean lineOriented)
{
    switch(documentStatus)
    {
        case DocumentStatus::Confirmation       :   return SalesEditLinesForm_Confirm::construct(lineOriented);
        case DocumentStatus::PickingList        :   return SalesEditLinesForm_PickingList::construct(lineOriented);
        case DocumentStatus::PackingSlip        :   return SalesEditLinesForm_PackingSlip::construct(lineOriented);
        case DocumentStatus::ProjectPackingSlip :   return SalesEditLinesForm_ProjectPackingSlip::construct(lineOriented);
        case DocumentStatus::Invoice            :   return SalesEditLinesForm_Invoice::construct(lineOriented);
    }

    throw error(strfmt("@SYS19306",funcname()));
}

En Dynamics AX no se suele usar una clase específica para la factoría sino que se suele implementar el constructor múltiple en la propia clase padre abstracta, pero el objetivo a cumplir es el mismo.

Por ejemplo, en la clase SysStartupCmd sí esta implementado de manera mas rigurosa, siendo este un mecanismo hook que el estándar nos ofrece para ampliar esta funcionalidad minimizando el impacto en las clases estándar (otra Best Practice) creando nuestras propias clases y enlazándolas mediante este constructor.

Por las particularidades técnias de Dynamics AX,  algunos de estos patrones están implementados mediante macros o mapas, como ya he comentado en artículos anteriores.

Bojan Jovičić en su blog ha implementado ejemplos de un buen número de patrones de diseño en X++ y los publica en un proyecto .xpo para su descarga. Una lectura recomendable, igual que los artículos oficiales de Best Practices de MSDN.