는 네,하지만, 인터페이스를 갖는 주입 종속성을 가진보다 우선 순위 이하, 좋은 시작이다)
는 "추출물 및 재정"에 대한 예를 들어 필요하면 알려주세요. 모든 레거시 클래스가 인터페이스를 얻지 만 내부적으로 숨겨진다면 여전히 상호 의존적이므로 클래스는 여전히 테스트하기가 쉽지 않습니다. 예를 들어, 당신이이 닮은 두 개의 클래스를 가지고 가정 해 봅시다 :
Public Class LegacyDataAccess
Public Function GetAllSales() As List(Of SaleDto)
' Do work with takes a long time to run against real DB
End Function
End Class
Public Class LegacyBusiness
Public Function GetTotalSales() As Integer
Dim dataAccess As New LegacyDataAccess()
Dim sales As List(Of SaleDto) = dataAccess.GetAllSales()
' Calculate total sales
End Function
End Class
나는 당신이 이미 ... 말을하는지 가 "나는 레거시 코드는 적어도 층이 아니라 좋겠어요"하지만 수 있습니다 알고 이를 테스트하기 어려운 기존 코드의 예제로 사용하십시오. 테스트하기 어려운 이유는 코드가 데이터베이스에 도달하여 데이터베이스에서 시간이 많이 소요되는 쿼리를 실행 한 다음 그 결과를 계산하기 때문입니다. 따라서 현재 상태에서 테스트하려면 먼저 테스트 데이터 묶음을 데이터베이스에 작성한 다음 코드를 실행하여 삽입 된 데이터를 기반으로 올바른 결과를 반환하는지 확인해야합니다. 때문에 그런 테스트를 작성할 수있는 것은 문제가있다 : 그것은 테스트를 셋업에 코드를 작성하는 고통이다
- 포함
- 제대로 작동 외부 데이터베이스에 의존하기 때문에 시험은 부서지기 쉬운 것입니다 그것에 모든 올바른 지원 데이터는
- 시험은 올바르게 관찰, 인터페이스는 단위 테스트에 매우 중요하다
실행하는 데 시간이 너무 오래 걸릴 것입니다. 당신이 추천 그래서, 그것은 수 있는지 확인하기 위해 인터페이스를 추가 할 수 있습니다 그것을 시험에 쉽게 하나를
Public Interface ILegacyDataAccess
Function GetAllSales() As List(Of SaleDto)
End Interface
Public Interface ILegacyBusiness
Function GetTotalSales() As Integer
End Interface
Public Class LegacyDataAccess
Implements ILegacyDataAccess
Public Function GetAllSales() As List(Of SaleDto) _
Implements ILegacyDataAccess.GetAllSales
' Do work with takes a long time to run against real DB
End Function
End Class
Public Class LegacyBusiness
Implements ILegacyBusiness
Public Function GetTotalSales() As Integer _
Implements ILegacyBusiness.GetTotalSales
Dim dataAccess As New LegacyDataAccess()
Dim sales As List(Of SaleDto) = dataAccess.GetAllSales()
' Calculate total sales
End Function
End Class
그래서 지금 우리가 인터페이스를 가지고 있지만, 정말, 어떻게이 쉽게 어떤 테스트 할 수 있도록 하는가? 이제 동일한 인터페이스를 구현하는 모의 데이터 액세스 객체를 쉽게 만들 수 있습니다.하지만 실제로 핵심적인 문제는 아닙니다. 문제는 실제 객체의 대신이라는 모의 데이터 액세스 객체를 사용하도록 비즈니스 객체를 얻는 방법입니다. 그렇게하려면 의존성 주입을 도입하여 리팩토링을 한 차원 높여야합니다.진짜 범인은 비즈니스 클래스의 다음 줄에 New
키워드입니다 :
Dim dataAccess As New LegacyDataAccess()
비즈니스 클래스는 명확하게 데이터 액세스 클래스에 따라 다르지만 현재는 그 사실을 숨기고있다. 의존성에 대해 거짓말하고 있습니다. 말하자면, 쉽고 간단합니다.이 메서드를 호출하면 결과를 반환 할 것입니다. 정말로, 그것은 그것보다 더 많은 것을 필요로합니다. 이제, 우리가 종속의 거짓말에서 중지와 같이, 그것은 그래서 당당를 언급했다 가정 해 봅시다 :
Public Class LegacyBusiness
Implements ILegacyBusiness
Public Sub New(dataAccess As ILegacyDataAccess)
_dataAccess = dataAccess
End Sub
Private _dataAccess As ILegacyDataAccess
Public Function GetTotalSales() As Integer _
Implements ILegacyBusiness.GetTotalSales
Dim sales As List(Of SaleDto) = _dataAccess.GetAllSales()
' Calculate total sales
End Function
End Class
를 이제, 당신이 볼 수 있듯이,이 클래스는 테스트 훨씬 쉽다. 모의 데이터 액세스 객체를 쉽게 만들 수있을뿐만 아니라 모의 데이터 액세스 객체를 비즈니스 객체에 쉽게 삽입 할 수 있습니다. 이제는 우리가 반환하고자하는 데이터를 빠르고 쉽게 반환 한 다음 비즈니스 클래스가 올바른 계산을 반환하는지 (데이터베이스가 관련되지 않음) 볼 수있는 모의 객체를 만들 수 있습니다.
불행히도 기존 클래스에 인터페이스를 추가하는 것은 쉽지만 종속성 주입을 사용하도록 리팩터링하는 데는 일반적으로 훨씬 많은 작업이 필요합니다. 어떤 수업이 가장 먼저 다루기에 가장 적합한지를 계획해야 할 것입니다. 코드를 사용하는 방식으로 작동하는 중개 구식 래퍼를 만들어야 할 수 있으므로 코드를 리팩터링하는 동안 기존 코드를 손상시키지 않아야합니다. 쉽고 빠르지는 않습니다. 그러나 장거리 노선을 위해 오래도록 인내심을 갖고 있다면, 그렇게 할 수 있으며, 기꺼이 할 수 있습니다.
DI 알림을 보내 주셔서 감사합니다. +1. – w0051977
그리고 포괄적 인 대답입니다. – w0051977
감사. 내 데이터웨어 하우스/VB.NET 질문을 여기에서 볼 수 있다면 감사하겠습니다. http://stackoverflow.com/questions/18495622/data-warehouse-type-solution#18495622. 디자인 패턴 유형 질문에 대한 좋은 답변을 제공하므로 요청할 것입니다. – w0051977