죄송 C#
선택의 나의 언어, 내가 읽을 수 Java
있지만, 아마도 그것을 쓰기를 시도하는 구문을 오거라 ... 같은 개념 사이에 적용 C#
하고 Java
있지만, 그래서 희망이 당신이 점점 더 될 당신의 코드베이스를 이동할 수있는 방법의 단계를 보여줍니다 테스트 가능.
주어진:
public class MyUI
{
public void SomeMethod()
{
Foo foo = new Foo();
foo.DoStuff();
}
}
public class Foo
{
public void DoStuff()
{
Bar bar = new Bar();
bar.DoSomethingElse();
}
}
public class Bar
{
public void DoSomethingElse();
}
IOC 컨테이너를 사용하지 않고 DI를 사용하도록 쉽게 리팩토링 할 수 있으며, 여러 단계로 나눌 수도 있습니다.
(잠재적) 1 단계-종속성을 취하지 만 호출 (UI) 코드를 변경하지 않음 :
public class MyUI
{
public void SomeMethod()
{
Foo foo = new Foo();
foo.DoStuff();
}
}
public class Foo
{
private IBar _iBar;
// Leaving this constructor for step one,
// so that calling code can stay as is without impact
public Foo()
{
_iBar = new Bar();
}
// simply because we now have a constructor that take's in the implementation of the IBar dependency,
// Foo can be much more easily tested.
public Foo(IBar iBar)
{
_iBar = iBar;
}
public void DoStuff()
{
_iBar.DoSomethingElse();
}
}
public interface IBar
{
void DoSomethingElse();
}
public class Bar
{
public void DoSomethingElse();
}
리 팩터 2 (또는 IOC 컨테이너를 구현하고 호출 코드를 즉시 변경하는 경우 첫 번째 리팩터링) :
public class MyUI
{
public void SomeMethod()
{
Foo foo = null // use your IOC container to resolve the dependency
foo.DoStuff();
}
}
public class Foo
{
private IBar _iBar;
// note we have now dropped the "default constructor" - this is now a breaking change as far as the UI is concerned.
// You can either do this all at once (do only step 2) or in a gradual manner (step 1, then step 2)
// Only entry into class - requires passing in of class dependencies (IBar)
public Foo(IBar iBar)
{
_iBar = iBar;
}
public void DoStuff()
{
_iBar.DoSomethingElse();
}
}
2 단계는 기술적으로 자체적으로 수행 될 수 있지만 현재 잠재적으로 DI에 찾고있는 기능을 "새로 고치는"클래스 수에 따라 훨씬 더 많은 작업이 될 것입니다.
1 단계-> 2 단계 라우트를 고려해보십시오 .에 대해 Foo
독립적으로 단위 테스트를 만들 수 있습니다 Bar
. 1 단계 리팩토링 이전에 두 클래스의 실제 구현을 사용하지 않으면 쉽게 달성 할 수 없었습니다. 1 단계-> 2 단계 (즉시 2 단계가 아닌)를 수행하면 시간이 지남에 따라 더 작은 변화가 허용되며 결과없이 리 팩터가 더 잘 작동하도록 테스트 하네스를 이미 시작할 수 있습니다.