2010-09-17 20 views
6

He estado investigando esto durante semanas. Actualmente estoy diseñando un diseño de arquitectura flojo usando el método n-tier (3 capas) y el enfoque de diseño de fábrica. Mi objetivo es poner la lógica de negocios de cada cliente (ClientA.DLL, ClientB.DLL) en espacios de nombres separados para que el proyecto se amplíe, lo que significa que puedo modificar/eliminar/agregar la lógica de negocios de un cliente específico sin afectar a los demás, porque son no dependientes el uno del otro. Luego invoco los espacios de nombres/clase del cliente utilizando el identificador único del cliente (un valor de cadena que se mantiene en la base de datos) a través del espacio de nombres de fábrica. El Factory.DLL también oculta la lógica por cliente, mientras que el BusinessAbstract.DLL sirve como el Diseño o la Plantilla que utilizarán las clases por cliente.Creación de una arquitectura de software escasamente acoplada/escalable

Aquí está la solución de proyecto:

alt text

Y aquí es el código real:

BusinessAbstract.DLL

namespace BusinessAbstract 
{ 
    // the entity/data transfer object 
    public class MemberDTO 
    { 
     public string MemberID { get; set; } 
     public string MemberName { get; set; } 
    } 

    // the interface 
    public interface IMaintainable 
    { 
     void Add(); 
     void Edit(); 
     void Delete(); 
    } 

    // the base abstract class, implements the Entity and the Interface 
    public abstract class Member : MemberDTO, IMaintainable 
    { 
    // Implement IMaintanable but change it to abstract 
    public abstract void Add(); 
    public abstract void Edit(); 
    public abstract void Delete(); 

    // a method with Database access, get from DAL 
    public virtual MemberDTO GetMemberDetails(params object[] args) 
    { 
     return DAL.MemberDAL.FetchMemberDetails(args); 
    } 

    public virtual string GetClientBLL() 
    { 
     return "base's method"; 
    } 
    } 
} 

aplicación cliente A de la AbstractBusinessRule

ClientA.DLL

namespace ClientA 
{ 
    public class _Member : BusinessAbstract.Member 
    { 
     public override void Add() 
     { 
     throw new NotImplementedException(); 
     } 

     public override void Edit() 
     { 
     throw new NotImplementedException(); 
     } 

     public override void Delete() 
     { 
     throw new NotImplementedException(); 
     } 

     public override string GetClientBLL() 
     { 
     return "ClientA Method"; 
     } 
    } 
} 

La fábrica

Factory.DLL aplicación

public static class Invoker 
{ 
    public static T GetMemberInstance<T>(string clientCode) 
     where T : Member, IMaintainable 
     { 
     Type objType = Type.GetType(clientCode + "._Member," + clientCode); 
     return (T)Activator.CreateInstance(objType); 
     } 
    } 

Muestra el nivel de presentación

la Web

protected void Page_Load(object sender, EventArgs e) 
{ 

    // invoke Member class using String hardcode 
    Member obj = Invoker.GetMemberInstance<Member>("ClientA"); 
    Response.Write(obj.GetClientBLL()); //prints clientA method 

    obj = Invoker.GetMemberInstance<Member>("ClientB"); 
    Response.Write(obj.GetClientBLL()); //prints clientB method 

} 

Y también se dará cuenta de que tengo una carpeta DAL en cada una de las DLL del cliente, así como la AbstractBusinessRule DLL, porque también quiero escalar la capa DAL y el uso de la estructura de capas "IU-BLL -DAL ".

Cualquier comentario/sugerencia sobre este diseño es bienvenido. Espero recibir sugerencias sobre cómo puedo mejorar esta estructura. Gracias por adelantado.

+0

¿Alguien puede decirme si el objeto de dominio es un término más o menos común que DTO? Solo pregunto porque nunca había escuchado hablar de DTO, pero la mayoría de la gente sabe a qué me refiero cuando digo domain object, y creo que eso es lo que hace el DTO. –

+0

Sí, creo que es solo un nombre antiguo del dominio./Objeto comercial o entidad. Valor Objeto que es ... – CSharpNoob

+2

DTO == objeto de transferencia de datos, pero no creo que el OP lo esté usando de esa manera. Especialmente teniendo en cuenta que los DTO generalmente no hacen mucho más que almacenar los datos para pasarlos, por lo que no es como si pusiera lógica de negocios allí o inicie operaciones de persistencia desde allí. – eglasius

Respuesta

0

Tiene una violación básica del Principio de Separación de Preocupaciones/Responsabilidad Individual: sus objetos comerciales saben de su almacenamiento.

La capa de datos de la arquitectura de 3 niveles debe ser responsable de las operaciones de CRUD, y se debe consultar para conocer las instancias de los objetos que los consumidores necesitan. Algo como esto:

Presentation Layer ------- Data Layer 
           || 
           || 
         Business Layer 

Esto permite que la capa de negocio se concentre en la implementación y mantiene las preocupaciones de persistencia fuera de ella. Si la capa de Presentación necesita un nuevo objeto comercial (para la creación), le pide la capa de datos.

+3

mi comprensión en la arquitectura de 3 niveles es Presentation - Business - Data, el PL no puede acceder directamente a la capa de datos. En mi ejemplo, DataObject (MemberDTO) es el objeto que se comunica de PL a DAL, no necesita crear un nuevo objeto comercial (para la creación) como lo que está diciendo.gracias por la entrada ^^ – CSharpNoob

+1

la arquitectura de 3 niveles generalmente significa que hay una capa de Presentación, Negocio y Datos. Por lo general, se construye de la manera que usted tiene, pero como puede ver, hay una mezcla de preocupaciones dentro de la capa de negocios, que es, con mucho, la pieza más importante para hacerlo bien. Mientras menos código pueda poner en algo, es más probable que sea correcto. – arootbeer

0

Mi primer comentario sería que sus nombres deben ser mucho más descriptivos.No es nada obvio lo que su programa realmente hace al mirar el esquema de la solución. Si le da a sus clases de clientes y su espacio de trabajo nombres significativos, será un paso en la dirección correcta.

+0

Creo que los nombres son solo ejemplos para ilustrar un punto. :) – bzlm

0

esta pregunta salió demasiado amplia, no hay un solo mejor enfoque para todos.

Personalmente, basar puntos de extensión en agregar clases y herencia sin un caso real que se beneficie mucho de ello es algo que he visto que termina en una gran complejidad.

Es muy difícil de decir con la cantidad de información proporcionada, pero considere la alternativa de utilizar un enfoque más basado en configuración/no significa archivos de configuración, solo configuraciones que se pasan al sistema.

Puede tener un conjunto de reglas básicas y una configuración predeterminada que aplique un conjunto de esas reglas a un cliente. Si lo hace en código, al agregar la configuración de un cliente, puede decir .AddClient ("ClientA") y solo usará las reglas predeterminadas.

De forma alternativa, puede especificar las reglas que se aplican a los procesos del cliente al agregar el cliente, lo que puede implicar el establecimiento de reglas diferentes o incluso valores de configuración diferentes para ellas.

ClientA puede tener una necesidad que no esté incluida en las reglas básicas, luego se puede aplicar una regla comercial personalizada/de código al proceso del cliente.

No trataría de dar el salto hasta un marco tan genérico. En cambio, mantendría lo anterior centrado en los procesos específicos y expondría los puntos de extensión para esos. A medida que trabaje en la solución, deberían surgir patrones comunes y luego, de ser apropiado (se puede ver un beneficio real), puede refactorizarlo a algo más general.

1

Lo único que veo, y me falta simplemente perder esto al mirar su publicación, pero no veo una definición de interfaz DAL o una capa de abstracción que la separe de su BL en la forma en que se abstrae su BL tu presentación.

Esto es importante porque le ofrece flexibilidad en el futuro para crear una nueva capa empresarial utilizando los mismos datos sin tener que reescribir el DAL o reemplazar su base de datos con archivos CSV planos/simulaciones en pruebas unitarias/un tercero mantuvo la respuesta del servicio web soap, o cualquier otra cosa que podría ser un mejor mecanismo de almacenamiento de datos en el futuro.

+0

YES el DAL está estrechamente relacionado con el BL porque los clientes tienen una implementación diferente en el DAL, y es difícil hacer un resumen de esto porque el cliente es debido a eso. pero tomaría la idea de también abstraer el DAL de BL. gracias por la entrada ^^ – CSharpNoob

+0

@CSharpNoob: Y es exactamente por eso que necesita una capa de abstracción DAL. Para que los clientes puedan tener diferentes implementaciones del DAL, sin tener que usar diferentes clientes para diferentes DAL. Un cliente que prueba lo mismo en una interfaz DAL, hará diferentes cosas dependiendo de la instancia del DAL que entregó a ese cliente. Esto permite que un cliente trabaje contra múltiples implementaciones DAL. Su estrecho acoplamiento requerirá múltiples implementaciones de cliente para múltiples implementaciones DAL. –

+0

gracias Jimmy, creo que tengo que considerarlo ... – CSharpNoob

Cuestiones relacionadas