2008-10-22 2 views
1

DAO를 사용하는 독학 vb6 프로그래머입니다.Refactor to n-tier

Sub cmdMultiplier_Click() 'Button on form, user interface ' 
    dim Rec1 as recordset 
    dim strSQL as string 

    strSQL = "select * from tblCustomers where ID = " & CurrentCustomerID 'inline SQL ' 
    set rec1 = GlobalDataBase.openrecordset(strSQL) ' Data access ' 

    if rec1.bof <> true or rec1.eof <> true then 
    if rec1.fields("Category").value = 1 then 
     PriceMultiplier = 0.9   ' Business Logic ' 
    else 
     priceMultiplier = 1 
    end if 
end if 
End Sub 

이 (가) 위의 CRUD 애플리케이션의 전체 소스 코드 척하십시오 : 아래는 내가 휘젓다 수있는 코드의 전형적인 조각의 예입니다. 이 디자인이 나쁘다는 것을 알고, 모든 것이 함께 섞여 있습니다. 이상적으로는 세 개의 개별 레이어, 사용자 인터페이스, 비즈니스 로직 및 데이터 액세스가 있어야합니다. 나는 이것이 바람직한 이유를 알아 낸다. 그러나 그것이 어떻게 끝났는지 모르겠다. 그리고 나는 그와 같은 분리가 왜 좋은지 완전히 이해하지 못하는 이유가 무엇인지를 으로 생각한다. 누군가가 위의 말도 안되게 위의 리팩토링을 할 수 있다면 길 아래에 더 많이있을 것이라고 생각합니다. 3 단계로 간단한 예를 들어보세요.

+0

간단히 말하면 너무 단순하기 때문에 이것을 리펙토링하는 것은 매우 어려울 것입니다. 3 단계 응용 프로그램을 사용하면 간단한 예제에 많은 복잡성이 생겨 3 계층 아키텍처가 일반적인 코드보다 간단하다는 것을 정확하게 설명하지 못합니다. – workmad3

+0

무슨 뜻인지는 알지만 그 일이 어떻게 진행되는지 알고 싶었습니다. 그것에 대해 조금 더 생각해 보니 계층으로 분리하는 것이 데이터베이스를 정규화하는 데 아마도 유사하다고 생각하십니까? 피상적 인 수준에서 어떤 보상도없이 복잡성을 추가하는 것으로 보입니다 – kjack

+0

예, 데이터베이스를 정규화하는 것은 유사합니다. 조지에 의해 나는 그가 그것을 얻었다 고 생각한다 (tm)! –

답변

3

사소한 예, 예,하지만 모든 기본적인 요소 :

여기에 아주 기본적인 의사 코드의 예입니다. 이것의 주된 이유는 "관심의 분리"원칙입니다. 즉, GUI는 GUI와 관련이 있으며 비즈 로직 레이어는 비즈니스 규칙에만 관련되며 데이터 액세스 레이어는 데이터 표현에만 관련됩니다. 이는 각 계층이 독립적으로 유지 및 애플리케이션에서 재사용 할 수 있습니다 :

'in Form class - button handler 
Sub cmdMultiplier_Click() 
    PriceMultiplier = ComputePriceMultiplier(CurrentCustomerId) 
End Sub 

'in Biz Logic class 
Function ComputePriceMultiplier(custId as Integer) as Double 
    Dim cust as Customer = GetCustomer(custId) 
    if cust.Category = 1 then 'please ignore magic number, real code uses enums 
     return 0.9 
    end if 
    return 1 
End Function 

'in Data Access Layer class 
Function GetCustomer(custId as Integer) as Customer 
    Dim cust as Customer = New Customer 'all fields/properties to default values 
    Dim strSQL as String = "select * from tblCustomers where ID = " & custId 
    set rec1 = GlobalDataBase.openrecordset(strSQL) ' Data access ' 
    if rec1.bof <> true or rec1.eof <> true then 
     cust.SetPropertiesFromRecord(rec1) 
    end if 
    return cust 
End Function 

[현재 고객을 캐시 것 '진짜'응용 프로그램 등 고객 쿼리에 대한 상수 또는 저장 프로 시저를 가지고; 간결함을 위해 무시 됨]

원래의 모든 걸음 걸이 처리기 예제와 비교해보십시오. (이 방법은 그렇게 쉽게하기 때문에 VB 코드에서 흔히 볼 수 있습니다.) - 가격 승수가 필요한 경우 규칙을 다른 응용 프로그램에서 사용하려면 해당 응용 프로그램의 단추 처리기에 코드를 복사, 붙여 넣기 및 편집해야합니다. 이제 동일한 비즈니스 규칙을 유지하는 두 곳과 동일한 고객 쿼리가 실행 된 두 곳이 있습니다.

+0

위대한 답변! 재배포하여 원래 코드를 보존하면 실제로 이해에 도움이됩니다. – kjack

+0

데이터 액세스 레이어에서 실제로 데이터를 가져 오는 단일 함수가 있어야할까요? 전체 응용 프로그램에서 이와 같은 단 한 줄만 입력하면됩니다. rec1 = GlobalDataBase.openrecordset (strSQL) – kjack

+0

@kjack 마지막 질문에 대한 쉬운 대답은 없습니다. 어떤 사람들은 그렇다고 말하고 어떤 사람들은 아니오라고 말할 것입니다. 그것은 나머지 아키텍처가 어떻게 생겼는지에 달려 있습니다. –

1

버튼의 용도는 무엇입니까?

나의 첫 번째 단계는 다음과 같습니다

  • 데이터베이스를 액세스하는 부분의 압축을 풉니 다. (주의 : 전방 공기 코드()만큼 CurrentCustomerID)

함수 getCustomer

STRSQL가 = &가 세트 rec1이 = GlobalDataBase.openrecordset (STRSQL) 결과 CurrentCustomerID "ID가 = tblCustomers * FROM"= 1

경우 rec1.recordcount> 0 다음 getCustomer = rec1이 다른 getCustomer = 거짓 ENDIF 단부 함수

"만약 고객 (다음 을

기능 getCustomerDiscount (롱 등 CUSTOMERID)

고객 = getCustomer (고객 ID)

입술 = 1 경우 고객 :

  • 는 비즈니스 로직 기능을 구성 카테고리 ") = 1) then res = .9 endif endif

    • 다음

      getcustomerdiscount = 입술

      단부 기능 버튼을 변경 :

    cmdMultiplier_Click()

  • 서브 pricemultiplier = getcustomerdiscount 전형적 (currentcustomerid) 최종 서브

+0

버튼을 사용하는 것을 잊어 버렸습니다. 어쩌면 레이블에 승수를 표시 할 수 있습니다. 답장을 보내 주신 스티븐 A. 로우 (Stephen A. Lowe)의 답변에 더 감사드립니다. – kjack

1

는 것 사용자가 제기 한 이벤트 (이 경우 버튼 클릭)에 응답하는 UI 코드를 갖습니다.

그런 다음 프로그램이 어떻게 설계되었는지에 따라 달라 지므로 가장 기본적인 설계는 고객 인스턴스를 참조하는 것이고 배율 속성을 포함하게됩니다. 고객 개체가 DAL의 데이터로 채워집니다.

UI 유효성 검사는 UI 레이어로 이동하고 비즈니스 유효성 검사 규칙은 비즈니스 개체로 전달 된 다음 DAL이 지속성 계층입니다. 그들은 단지 3 개 개의 다른 클래스에 속하는 (아래 참조) -

btnClick 
    Dim Cust as New Customer(ID) 
    multplr = Cust.DiscountMultiplier 
End Click 

Class Customer 
    Sub New(ID) 
     Data = DAL.GetCustomerData(ID) 
     Me.Name = Data("Name") 
     Me.Address = Data("Address") 
     Me.DiscountMultiplier = Data("DiscountMultiplier") 
    End Sub 
    Property ID 
    Property Name 
    Property Address 
    Property DiscountMultiplier 
     Return _discountMultiplier 
    End 
End Class 


Class DAL 
    Function GetCustomerData(ID) 
     SQL = "Paramaterized SQL" 
     Return Data 
    End Function 
End Class 
+0

스티븐 로우 (Stephen A Lowe)의 대답을 받아 들였습니다. 비록 객관적으로 객관적으로 대답하는 것이 좋을지는 모르지만, 조금 더 잘 이해했기 때문에 받아 들였습니다. – kjack

1

리팩토링하는 방법을 아는 것은 좋은 일입니다. 이제는 레이어를 분리하는 방법을 알게 될 것입니다.
그러나 귀하의 시간은 동시에 사용하는 도구를 업그레이드하는 데 더 많은 시간을 소비 할 것으로 생각됩니다. 당신은 VB.Net을 가지고 그것을 고려해야합니까?

기존 코드베이스를 보존하는 방법은 VB.Net에서 데이터 레이어와 BR을 코딩하는 것입니다. 그런 다음 BR을 COM 인터페이스를 통해 노출합니다 (이 옵션은 프로젝트의 확인란 옵션입니다). 그런 다음 현재 인터페이스에서 새 BR을 사용할 수 있습니다.

BR과 DAL이 모두 완료되면 완전히 새로운 플랫폼으로 한발 더 나아갈 수 있습니다.

+0

그건 좋은 지적입니다. 나는 미래에 .net에 모든 것을 포팅하는 것에 대해 생각하고있다. 그러나 vb6에는 여전히 몇 년이 남았다. 기존 응용 프로그램을 유지 관리, 향상 및 리팩토링하는 것이 더 쉬울 수도 있고 이미 익숙한 환경에서 OOP 등을 배울 수도 있습니다. – kjack

관련 문제