2013-01-01 6 views
7

아래 코드를 참조하십시오 BLL과 DAL (데이터 액세스 계층)에 (비즈니스 로직 계층) :속보 BLL

Imports Microsoft.VisualBasic 

Public Class PersonBLL 
    Private Name As String 
    Private Age As Integer 

    Dim objPersonDAL As New PersonDAL 
    Dim objPerson As Person 

    Public Sub getPersonByID() 
     objPerson = objPersonDAL.getPersonByID() 
     MsgBox(objPerson.Name) 
    End Sub 
End Class 

Public Class PersonDAL 
    Private Name As String 
    Private Age As Integer 

    Public Function getPersonByID() As Person 
     'Connect to database and get Person. Return a person object 
     Dim p1 As New Person 
     p1.Name = "Ian" 
     p1.Age = 30 
     Return p1 
    End Function 
End Class 

Public Class Person 
    Private _Name As String 
    Private _Age As Integer 

    Public Property Name() As String 
     Get 
      Return _Name 
     End Get 
     Set(ByVal value As String) 
      _Name = value 
     End Set 
    End Property 

    Public Property Age() As Integer 
     Get 
      Return _Age 
     End Get 
     Set(ByVal value As Integer) 
      _Age = value 
     End Set 
    End Property 
End Class 

PersonBLL는 PersonDAL를 호출하고 Person 객체를 반환합니다. 이것이 올바른 접근 방법입니까? 즉, 영구 클래스를 식별하고 데이터에 액세스하고 Person 객체를 반환하는 함수가있는 해당 DAL 클래스를 만들었습니다.

이 질문은 "주관적인"의견이 있습니다. 나는 이것에 동의한다. 디자인이 프로젝트의 요구 사항에 달려 있다는 것을 알고 있습니다. 솔리드 (단일 책임 등)와 유사한 DAL을 설계하기위한 모든 원칙이 있습니까?

+0

는 "올바른 접근 방식은"다소 주관적 의미를 정확하게 무엇인지 지정되도록, 인터페이스 같은 것에 대해 관심 . "이것이 유효한 접근인가?"라고 대답 할 수있다. 나는 "그렇다"라고 말하고 싶다. – David

+0

@ David Stratton, 질문을 업데이트했습니다. 데이터 액세스 레이어 설계와 관련이있는 SOLID와 같은 원칙을 알고 계십니까? – w0051977

+0

좋은 편집. 나는 이보다 더 똑똑한 사람들을 대답하게 할 것이다. 이것은 나의 전문 분야가 아니며,이 사이트의 대부분의 사람들은 저보다 훨씬 똑똑한 지옥입니다. 나는 너를 틀리게 조종 할 것이다. 필자가 제공해야하는 것은 이전에이 디자인을 .NET 이외의 배경을 가진 사람들로부터 보았습니다. 일반적으로 보입니다. 나는 개인적으로 지루한 것을 발견한다. 그러나 내가 말했던 것처럼, 나는 블록에서 가장 똑똑한 사람이 아니다. – David

답변

6

네 질문은 로직을 레이어로 분리하는 매우 깨끗한 방법을 보여줍니다. PersonBLL 클래스는 비즈니스 계층의 일부이고 PersonDAL 클래스는 데이터 액세스 계층의 일부가되며 Person 클래스는 데이터 전송 개체 (DTO) 계층의 일부가됩니다. 이는 여러 상황에서 잘 작동하는 레이어를 분리하는 가장 일반적인 방법입니다.

내 유일한 권고는 다음과 같습니다

  • 당신은 자신의 네임 스페이스하지 않을 경우에도 자신의 클래스 라이브러리 프로젝트를 각 레이어를 넣어해야합니다.
  • 비즈니스 계층에서 메시지 상자를 표시하면 안됩니다. 나는 당신이 시위의 수단으로 만 이것을했다고 가정하지만, 만약의 경우에, 나는 그것을 언급해야한다고 생각했다. 메시지 상자를 표시하는 것은 UI 레이어의 일부 여야합니다. 예를 들어, Windows 서비스 또는 웹 서비스에서 PersonBLL.getPersonByID을 호출하는 경우 메시지 상자를 표시하는 것은 전적으로 부적절합니다.
  • 일반적으로 모든 방법은 낙타 사례가 아닌 PascalCase입니다. 어떤 사람들은 개인적인 방법으로 낙타의 경우를 선호하지만, 확실히 공공의 방법은 낙타의 경우가되어서는 안됩니다.
  • 데이터 액세스 오브젝트를 비즈니스 오브젝트에 삽입하기 위해 종속 삽입 기술 (DI) 사용을 고려하십시오.

    Public Class BusinessFactory 
        Public Function NewPersonBusiness() As IPersonBusiness 
         Return New PersonBusiness(New PersonDataAccess()) 
        End Function 
    End Class 
    
    Public Class PersonBusiness 
        Implements IPersonBusiness 
    
        Public Sub New(personDataAccess As IPersonDataAccess) 
         _personDataAccess = personDataAccess 
        End Sub 
    
        Private _personDataAccess As IPersonDataAccess 
    
        Public Function GetPersonByID() As PersonDto Implements IPersonBusiness.GetPersonByID 
         Return _personDataAccess.GetPersonByID() 
        End Sub 
    End Class 
    
    Public Interface IPersonBusiness 
        Function GetPersonByID() As PersonDto 
    End Interface 
    
    Public Interface IPersonDataAccess 
        Function GetPersonById() As PersonDto 
    End Interface 
    
    Public Class PersonDto 
        Private _name As String 
        Private _age As Integer 
    
        Public Property Name() As String 
         Get 
          Return _name 
         End Get 
         Set(ByVal value As String) 
          _name = value 
         End Set 
        End Property 
    
        Public Property Age() As Integer 
         Get 
          Return _age 
         End Get 
         Set(ByVal value As Integer) 
          _age = value 
         End Set 
        End Property 
    End Class 
    

    이 방법은 많은 장점을 가지고 그 일 :

의존성 삽입 (Dependency Injection)

여기 DI 기술로이 작업을 수행하는 방법의 예입니다. 상호 교환 가능한 데이터 액세스 레이어 구현을 여러 개 가질 수 있으므로 유연성이 향상됩니다. 또한 비즈니스 클래스를 단위 테스트하려는 경우 가짜 데이터 액세스 객체를 삽입 할 수 있습니다. DI 디자인은 버그, 스파게티 코드로 이어지는 많은 트랩을 피합니다.

DI를 사용하면 일반적으로 구체 유형이 아닌 인터페이스로 종속 개체를 요청하는 것이 좋습니다 (예 : PersonDataAccess이 아닌 IPersonDataAccess). 이렇게하면 번거 로움이 될 수 있지만 빨리 익숙해집니다. 이 시점에서 모든 클래스에 대해 하나의 인터페이스를 만드는 경우가 많으므로 인터페이스를 클래스와 동일한 코드 파일에 두는 것이 편리합니다. 예를 들어 PersonBusiness.vb에는 PersonDataAccess 클래스와 IPersonDataAccess 인터페이스가 모두 포함됩니다.

의존성를 들어, 클래스보다는 인터페이스를 사용하는 두 가지 이유가 있습니다 중요하다 :

  1. 그것은 디자인이 유연 보장합니다. 모든 종류의 구체적인 구현을 만들 수 있도록 종속성 형식의 모든 public 멤버를 재정의 할 수 있어야합니다. 이를 수행하는 다른 방법이 있습니다. 예를 들어 PersonDataAccess 클래스의 모든 공용 속성 및 메서드를 Overrideable 수정 자로 표시하여 IPersonDataAcess 인터페이스를 만드는 것을 건너 뛸 수는 있지만이를 수행 할 필요는 없습니다. 항상 그렇게 생각한 경우라도 그것이 코드에서 작업하는 다른 사람이해야한다는 것을 알 수있는 것은 아닙니다.

    DI는 종종 코드를 테스트 할 수있는 최상의 도구이기 때문에 단위 테스트로 묶여 있습니다. 단위 테스트를 수행 할 때 종속성 유형의 멤버를 무시할 수 있으므로 단위 테스트를 올바르게 수행하기 위해 필요한 방식으로 작동하는 "가짜"객체를 만들 수 있어야합니다. 이러한 "가짜"객체는 모크입니다.

  2. 당신의 의존성이 무엇보다 기술적으로 정직합니다. 사실 실제로 의존성이 실제로 PersonDataAccess 클래스의 인스턴스라고 말하지는 않습니다. 사실, 당신의 의존성은 같은 공용 인터페이스를 가지고있는 모든 객체입니다. 수업에 대해 질문하면 특정 구현이 필요하다는 것을 암시합니다. 이는 거짓말입니다. 당신이 제대로 설계 한 경우에만 인터페이스 만 자체에 대한 요구해서, 당신은 당신이 지정 :)

+0

감사합니다. +1에 대한 참조. 모든 클래스의 인터페이스를 만들겠습니까? PersonDto는 어디에 정의되어 있습니까? Person 클래스와 같다고 가정합니다. – w0051977

+0

예, 'PersonDto'는 내 질문에'Person' 클래스와 동일한 것으로 가정합니다. 혼란을 드려 죄송합니다. 예, 모든 비 DTO 클래스에 대한 인터페이스를 만드는 것이 좋습니다. 본질적으로 하나의 클래스만을위한 인터페이스를 만들면 클래스와 동일한 코드 파일에 배치하는 것이 좋습니다. 예를 들어, PersonBusiness.vb는'PersonBusiness' 클래스와'IPersonBusiness' 인터페이스를 모두 포함합니다. –

+0

나는 클래스 파일과 인터페이스를 프로젝트를 선언하는 것과 같은 파일에 넣는 것을 좋아한다. 인터페이스의 이점을 완전히 이해하지 못합니다. 시스템에 변경이 필요한 경우 반드시 변경이 필요합니다. 인터페이스가 있는지 여부는 중요하지 않지만 온라인으로 보이는 모든 곳에서 인터페이스를 제안하는 것처럼 보입니다. 당신의 대답을 받아들이 기 전에 예를들 수 있습니까? 감사. – w0051977