2009-11-23 2 views
6

그래서 내 프로그램 초안을 만들고 있습니다.비즈니스 로직이 데이터 계층과 어떻게 상호 작용해야합니까?

GUI 
--- 
Business Logic 
--- 
Data 

당신은 문제없이 하나 GUI 또는 Data 계층을 교체 할 수 있어야한다 :

이것은 내 계획이다. 모든 레이어가 스스로를 감시합니다. 따라서 GUIBusiness logic에서 메소드를 호출하고 메소드는 항상 상태와 일부 데이터를 리턴합니다. GUI가 데이터에 응답하는 방법은 항상 GUI 계층에서 결정되어야합니다. 비즈니스 로직은 이에 영향을 미치지 않아야합니다. 그래서 GUI와 비즈니스 로직과의 관계가 해결되었습니다. 나를 따라 오길 바랍니다.

이제 좀 더 구체적으로 살펴 보겠습니다. 데이터 계층에 대한 내 계획은 데이터베이스를 사용하는 것입니다. 이제 Business Logic이 데이터 계층에서 메소드를 호출해야합니까?

아마도 열거 형을 작성해야합니다. 이는 데이터 영역에서 인식하고있는 다른 하드 코딩 된 SQL 쿼리에 해당합니다.

예.

Datalayer.GetResults(Queries.GetAllCustomersIDs); 

검색어가 enum입니다.

이것이 올바른 방법이라면 GetResults는 무엇을 반환해야합니까? 문자열 배열? 질의에 다차원 데이터가 있다면?

대신 두 가지 일반적인 방법을 사용해야합니까?

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

아니면 각 종류의 데이터 요청에 대한 쿼리가 있어야합니까?

Datalayer.GetAllCustomerIDs; 
DataLayer.GetAllCustomers; 

답변

7

은 다음과 같습니다

데이터 층 :

데이터 액세스를 위해, 나는 각 개체를 들어, 인터페이스를 만들 수 있습니다. 각 인터페이스에는 해당 객체에 대한 모든 공용 데이터 액세스 메소드가 나열됩니다. 데이터를 보유하기 위해 각 객체에 대한 컨테이너 유형을 작성합니다.이 유형은 구조 또는 단순한 클래스 만 데이터로 사용할 수 있습니다. 또한 목록과 같은 언어 데이터 세트를 사용하여 데이터를 보관하므로 특정 데이터베이스 유형에 연결되지 않습니다. 그런 다음 데이터 인터페이스를 구현하는 클래스를 만들고이 클래스는 모든 SQL을 가지며 데이터베이스에 액세스하므로 데이터 저장 기술이 변경된 경우이 클래스 만 변경됩니다.

비즈니스 계층 :

데이터는 모든 논리가 확인하는 방법은 데이터 인터페이스로부터 느릅 메소드가 호출되는 순서되어야 않는다.이 클래스는 데이터 유형이 위에 언급 된 컨테이너 인 컨테이너 (예 : 목록)를 사용하여 데이터 저장소 또는 GUI로 데이터를 받아 "보냅니다".

GUI :

통화 비즈니스 로직 방법과 표시/포맷 데이터 프리젠 테이션. 비즈니스 논리의 올바른 방법을 호출하는 것 외에 다른 논리는 없습니다. 컨테이너의

작은 코드 예제 (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; 
    } 

} 

이 비즈니스 로직의 예는 실제로 매우 간단, 단지 스토리지 계층에서 데이터를 검색하지만,하는 방법을 보여줍니다만큼 당신이 데이터에 액세스 할 수로 , 당신은 당신이 원하는 방식으로 조작 할 수 있습니다. 여기에 단지 의견 : 어쩌면이 솔루션은 많은 메모리를 사용할 수 있기 때문에 수천 개의 요청이있는 매우 바쁜 서버에서 구현 된 경우 다시 고려해야합니다.

비즈니스 로직 및 UI 관점에서 모든 데이터는 목록과 같은 범용 컨테이너를 사용하여 모듈간에 전달됩니다. 모든 모듈 간의 연결 지점은 컨테이너 클래스이므로 모든 클래스가 잘 분리되지 않습니다.

UI는 비즈니스 로직 클래스에 대한 요청을 만들어 서비스 공급자처럼 작동합니다. 그렇게하면 UI를 변경해도 UI 아래의 클래스에는 영향을주지 않습니다.

비즈니스 로직은 범용 데이터를 사용하여 데이터 저장소 클래스에 데이터를 요청하고 전송하므로 데이터베이스/저장소 기술을 변경해도 영향을 미치지 않습니다.

그게 내가하는 데 사용하는 방법이고, 그것을 개선하기 위해 노력하고있어.)

+0

비즈니스 로직이 데이터 영역에서 일부 데이터를 가져 오는 경우를 예로 들겠습니까? – CasperT

+0

컨테이너 등으로 무엇을 의미하는지 이해합니다. 하지만 여전히 데이터를 가져와야하는 방법을 잘 모릅니다. 어느 쪽이 가장 좋습니다. – CasperT

+0

나는 이것으로 인해 버려지고 있다고 생각한다 : "각 인터페이스는 문제의 객체에 대한 모든 공용 데이터 액세스 메소드를 나열합니다."나는 작은 예제를 정말 감사 할 것입니다. – CasperT

2

귀하의 데이터 "계층"아마 의미 쿼리의 집합보다 더해야하며, 그렇지 않으면 당신의 비즈니스 로직 계층은에 대해 너무 많이 알고있을 것이다,하는 API에 캡슐화한다 귀하의 데이터 계층의 구현. GUI와 비즈니스 로직 계층 사이에서 사용한 것과 같은 추론이 적용되어야하며 동일한 목적으로 사용해야합니다. 내가 할 무엇을 사용 일반적으로

+0

당신은 이것의 예를 보여줄 수 있습니까? – CasperT

관련 문제