2009-11-23 6 views
6

Así que estoy trabajando en hacer un borrador de mi programa.¿Cómo debería interactuar mi lógica empresarial con mi capa de datos?

Este es mi plan:

GUI 
--- 
Business Logic 
--- 
Data 

Usted debe ser capaz de reemplazar cualquiera GUI o la capa Data sin problemas. Cada capa se ve a sí misma. Por lo tanto, GUI llamará a los métodos desde Business logic y los métodos siempre devolverán un estado y tal vez algunos datos. Cómo debe responder la GUI a los datos, siempre debe decidirse en la capa de la GUI. La lógica empresarial no debería tener influencia sobre esto. Por lo tanto, las relaciones con la GUI y la lógica empresarial se han resuelto. Espero que me puedas seguir.

Ahora para algo más concreto. Mi plan para la capa de datos, es usar una base de datos. Ahora, ¿cómo debería Business Logic llamar a los métodos de la capa de datos?

Quizás debería hacer una enumeración, que corresponde a diferentes consultas SQL codificadas, que la capa de datos conoce?

E.g.

Datalayer.GetResults(Queries.GetAllCustomersIDs); 

Queries being an enum.

Si esta es la manera correcta, ¿qué debería devolver GetResults? una matriz de cuerdas? pero ¿y si la consulta tiene datos multidimensionales?

¿Debo entonces tener 2 métodos genéricos?

Datalayer.GetSingleDimensionResults(SingleDimensionQueries.GetAllCustomersIDs); 
Datalayer.GetMultipleDimensionResults(MultiDimensionQueries.GetAllCustomers); 

¿O debería tener una consulta para cada tipo de solicitud de datos?

Datalayer.GetAllCustomerIDs; 
DataLayer.GetAllCustomers; 

etc.

Respuesta

7

En general, lo que utilizo para hacer es: capa

datos:

Para el acceso a datos, que crear una interfaz, para cada objeto. Cada interfaz enumera todos los métodos públicos de acceso a datos para el objeto en cuestión. Para contener los datos, creo tipos de contenedores, también para cada objeto, que pueden ser estructuras o clases simples solo con datos. También confío en el conjunto de datos de idiomas, como listas, para almacenar mis datos, por lo que no estoy vinculado a un tipo de base de datos en particular. Después de eso, creo una clase que implementa las interfaces de datos, esta clase tiene todos los SQL y accede a la base de datos, por lo que en caso de cambio en la tecnología de almacenamiento de datos, esta es la única clase que se cambiará.

Capa de negocio:

¿Tiene toda la lógica con los datos, cómo validar, wich métodos de las interfaces de datos debe ser llamado y en qué orden.Esta clase recibe y "envía" datos al almacenamiento de datos o GUI, usando contenedores (listas por ejemplo) donde los tipos de datos son mis contenedores mencionados anteriormente.

GUI:

llama a los métodos de lógica de negocio y presentación de datos mostrar/formato. Aquí no hay lógica más que llamar a los métodos correctos de la lógica comercial.

Pequeño ejemplo de código de un contenedor (C#)

//Interface for Department class data access. DataStorage assembly 

    namespace DataStorage 
    { 
     public interface IDepartmentDS 
     { 
      void Open(); //Open data conection 
      void Close(); //Close data conection 
      List<Repositories.Department> List(); //Gets all departments (from data base) 
     } 
    } 


    //This class holds all data regarded a department. There's no logic here. Repositories assembly 

    namespace Repositories 
    { 
     public class Department 
     { 
      [Browsable(false)] 
      public Department() 
      { 
      } 

      [Browsable(false)] 
      public Department(String Symbol, String Name) 
      { 
       this.Symbol = Symbol; 
       this.DeptName = Name; 
      } 

      public Department(Department department) 
      { 
       this.Symbol = department.Symbol; 
       this.DeptName = department.DeptName; 
      } 

      [Browsable(false)] 
      public String Symbol { get; set; } 

      public String DeptName { get; set; } 
     } 
    } 


    //This class implements the data manipulation itself, accessing the real database. 
    //However the data exchange outside this class is done via repositories classes and 
    //Generics - Lists mainly 

    public class DataStorage : IDepartmentDS 
    { 
     //Here I use to put generic functions to connect with the database, format stored 
     //procedure parameters list etc. 

     //Implementation of the List method declare in the Department Interface 
      List<Repositories.Department> IDepartmentDS.List() 
      { 
       String query = String.Format("SELECT * FROM {0}", DepartmentTable); 
       int rows = 0; 
       DataSet ds = ExecSqlCommand(query, out rows); //this method is private to this class 

       if (ds == null) 
        return null; 

       List<Repositories.Department> list = new List<Repositories.Department>(); 
       foreach (DataRow row in ds.Tables[0].Rows) 
       { 
        list.Add(new Repositories.Department((String)row[DepFN_Symbol], (String)row[DepFN_DepName])); 
        //DepFN_Symbol and the others are just const variables representing the column index 
       } 

       return list; 
      } 

    } 

public class DepartmentLogic 
{ 
    public DepartmentLogic() 
    { 
     ..... 
    } 

    public List<Repositories.Department> GetAllDepartments() 
    { 
     //Here I create an Instance of the DataStorage but using the Department interface 
     //so I restrict the access to Department data methods only. It could be a good 
     //idea here to use the factory pattern. 

     IDepartmentDS department = (IDepartmentDS) new DataStorage(); 
     department.Open(); 

     List<Repositories.Department> departments = department.List(); 

     department.Close(); 

     return departments; 
    } 

} 

Este ejemplo de lógica de negocios es, de hecho, muy simple, sólo se muestra cómo recuperar los datos de la capa de almacenamiento, pero siempre y cuando usted tiene acceso a los datos , puedes manipularlo de la manera que quieras. Solo un comentario aquí: tal vez esta solución debería ser repensada si se implementa en un servidor muy ocupado con miles de solicitudes porque puede usar mucha memoria.

Para la lógica de negocios y también el punto de vista de la interfaz de usuario, todos los datos se comunican entre módulos usando contenedores de uso general como listas. El punto de enlace entre todos esos módulos son las clases de contenedores, por lo que todas las clases están menos desacopladas.

UI hace requisiciones para las clases de lógica de negocios, por lo que actúa como un proveedor de servicios. Si lo hace de esa manera, cambiar la UI no afectará las clases que se muestran a continuación.

La lógica de negocios solicita y envía datos a las clases de almacenamiento de datos usando datos de propósito general, por lo que cambiar la base de datos/tecnología de almacenamiento no debería afectarlo.

Esa es la forma que utilizo para hacer y estoy tratando de mejorarlo;)

+0

¿Podría dar un ejemplo en el que la lógica comercial recupera algunos datos de la capa de datos? – CasperT

+0

Entiendo lo que quiere decir con contenedores, etc. Pero aún no estoy seguro de cómo debería recuperar los datos, de qué manera es el mejor. – CasperT

+0

Creo que estoy siendo rechazado por esto: "Cada interfaz enumera todos los métodos públicos de acceso a datos para el objeto en cuestión." Realmente apreciaría algunos pequeños ejemplos – CasperT

2

su "capa" de datos probablemente debería ser más que un conjunto de consultas semánticas y se debe encapsular en una API, de lo contrario su capa de lógica de negocios tendrá que saber demasiado acerca de la implementación de su capa de Datos. Se debe aplicar el mismo razonamiento que ha utilizado entre sus capas de GUI y Business Logic, y para el mismo propósito.

+0

podría mostrar un ejemplo de este parecería? – CasperT

Cuestiones relacionadas