의존성 주입과 서비스 로케이터 패턴의 차이점은 무엇입니까?


304

두 패턴 모두 제어 역전 원리를 구현 한 것처럼 보입니다. 즉, 객체는 의존성을 구성하는 방법을 알아야합니다.

DI (Dependency Injection)는 생성자 또는 setter를 사용하여 종속성을 "주입"하는 것으로 보입니다.

생성자 주입 사용 예 :

//Foo Needs an IBar
public class Foo
{
  private IBar bar;

  public Foo(IBar bar)
  {
    this.bar = bar;
  }

  //...
}

Service Locator는 "컨테이너"를 사용하는 것으로 보입니다. "컨테이너"는 종속성을 연결하고 foo에게 막대를 제공합니다.

서비스 로케이터 사용 예 :

//Foo Needs an IBar
public class Foo
{
  private IBar bar;

  public Foo()
  {
    this.bar = Container.Get<IBar>();
  }

  //...
}

우리의 의존성은 단지 객체 그 자체이기 때문에, 이러한 의존성은 더 많은 의존성 등을 갖는 의존성을 가지고 있습니다. 따라서, 제어 컨테이너의 반전 (또는 DI 컨테이너)이 탄생했습니다. 예 : Castle Windsor, Ninject, Structure Map, Spring 등)

그러나 IOC / DI 컨테이너는 정확히 서비스 로케이터처럼 보입니다 . DI 컨테이너라고하는 것이 나쁜 이름입니까? IOC / DI 컨테이너는 또 다른 유형 의 Service Locator입니까? 의존성이 많을 때 DI 컨테이너를 주로 사용한다는 사실의 뉘앙스입니까?


13
제어의 역전은 "객체가 의존성을 구성하는 방법을 몰라서는 안된다"는 의미입니까?!? 저것은 나에게 새로운 것입니다. 아니, 실제로, 그것은 "제어의 역전"이 의미하는 것이 아닙니다. 참조 martinfowler.com/bliki/InversionOfControl.html를 문서에도 1980 년대에 다시 데이트, 용어의 어원에 대한 참조를 제공한다.
Rogério


1
Mark Seemann은 Service Locator를 안티 패턴 ( blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern ) 이라고 주장 합니다. 또한 다이어그램 (여기서는 stackoverflow.com/a/9503612/1977871 )이 DI 및 SL의 어려움을 이해하는 데 도움이된다는 것을 알았습니다 . 도움이 되었기를 바랍니다.
VivekDev

답변:


181

차이는 약간 보일 수 있지만 ServiceLocator를 사용하더라도 클래스는 여전히 해당 종속성을 작성해야합니다. 서비스 로케이터를 사용하여 수행합니다. DI를 사용하면 클래스에 종속성이 부여됩니다. 그들이 어디에서 왔는지 알거나 신경 쓰지 않습니다. 이것의 중요한 결과 중 하나는 DI 예제가 훨씬 더 쉽게 단위 테스트를 수행 할 수 있다는 것입니다. 종속 개체의 모의 구현을 전달할 수 있기 때문입니다. 두 가지를 결합하여 원하는 경우 서비스 로케이터 (또는 공장)를 주입 할 수 있습니다.


20
또한 클래스를 만들 때 두 가지를 모두 사용할 수 있습니다. 기본 생성자는 SL을 사용하여 종속성을 검색하고 해당 종속성을받는 "실제"생성자로 전달할 수 있습니다. 두 세계의 장점을 모두 누리십시오.
Grant Palin

6
아니요, ServiceLocator는 주어진 종속성 (플러그인)에 대한 올바른 구현을 인스턴스화하는 책임을집니다. DI의 경우, DI "컨테이너"가이를 담당합니다.
Rogério

5
@Rogerio 예. 클래스는 여전히 서비스 로케이터에 대해 알아야합니다. 또한 서비스 로케이터가 필요한 일시적인 객체에 대한 조회를 위해 Service Locator가 DI 컨테이너에 위임되는 것을 보았습니다.
Adam Gent

2
@Adam 서비스 로케이터가 DI 컨테이너에 위임한다고 말하지 않았습니다. "공식"기사에 설명 된 두 가지 상호 배타적 인 패턴 입니다. 나에게는 서비스 로케이터가 실제로 DI보다 큰 장점을 가지고 있습니다.
Rogério

3
"이것의 한 가지 중요한 결과는 DI 예제가 훨씬 더 쉽게 단위 테스트를 할 수 있다는 것입니다. 종속 개체의 구현을 모의 할 수 있기 때문입니다." 사실이 아니다. 단위 테스트에서 서비스 로케이터 컨테이너의 레지스터 기능에 대한 호출을 사용하여 레지스트리에 목업을 쉽게 추가 할 수 있습니다.
Drumbeg

93

서비스 로케이터를 사용하면 모든 클래스가 서비스 로케이터에 종속됩니다. 의존성 주입의 경우에는 그렇지 않습니다. 종속성 인젝터는 일반적으로 시작시 한 번만 호출되어 일부 기본 클래스에 종속성을 주입합니다. 이 주요 클래스가 의존하는 클래스는 완전한 객체 그래프가 나타날 때까지 반복적으로 종속성을 주입합니다.

좋은 비교 : http://martinfowler.com/articles/injection.html

의존성 인젝터가 클래스가 인젝터를 직접 호출하는 서비스 로케이터처럼 보이는 경우, 이는 종속성 인젝터가 아니라 서비스 로케이터 일 것입니다.


17
그러나 런타임 중에 객체를 만들어야하는 경우를 어떻게 처리합니까? "new"를 사용하여 수동으로 생성하면 DI를 사용할 수 없습니다. DI 프레임 워크에 도움을 요청하면 패턴이 깨집니다. 어떤 옵션이 남아 있습니까?
보리스

9
@Boris 나는 같은 문제가 있었고 클래스 특정 공장을 주입하기로 결정했습니다. 예쁘지 않지만 작업을 완료했습니다. 더 예쁜 솔루션을보고 싶습니다.
Charlie Rudenstål


2
@Boris 새 객체를 즉석에서 생성해야하는 경우 해당 객체에 대한 추상 팩토리를 주입합니다. 이 경우 서비스 로케이터를 주입하는 것과 비슷하지만 관련 객체를 빌드하기위한 구체적이고 균일 한 컴파일 타임 인터페이스를 제공하고 종속성을 명시 적으로 만듭니다.
LivePastTheEnd

51

서비스 로케이터는 종속성을 숨 깁니다. 로케이터에서 연결을 확보 할 때 객체가 데이터베이스에 도달했는지 여부 (예 :)를 통해 알 수 없습니다. 의존성 주입 (적어도 생성자 주입)을 사용하면 종속성이 명시 적입니다.

또한 서비스 로케이터는 다른 개체의 종속성에 대한 글로벌 액세스 지점을 제공하기 때문에 캡슐화를 중단합니다. 단일 위치와 마찬가지로 서비스 로케이터 사용 :

클라이언트 객체의 인터페이스에 대한 사전 및 사후 조건을 지정하기가 어려워집니다. 구현 작업은 외부에서 방해받을 수 있기 때문입니다.

종속성 주입을 사용하면 객체의 종속성이 지정되면 객체 자체를 제어 할 수 있습니다.



2
나는 ol 'Steve Yegge를 좋아하고 그 기사의 제목은 훌륭하지만, 내가 인용 한 기사와 Miško Hevery의 "Singletons are 병리학 거짓말 쟁이"( misko.hevery.com/2008/08/17/singletons-are-pathological- liars )는 특정 서비스 악마 위치 찾기에 대해 더 나은 사례를 만듭니다.
Jeff Sternal

이 답변은 서비스 로케이터를 가장 잘 정의하기 때문에 가장 정확합니다. "종속성을 숨기는 클래스" 내부적으로 종속성을 작성하는 것은 좋지 않지만 종종 클래스를 서비스 로케이터로 만들지는 않습니다. 또한 컨테이너에 대한 종속성을 갖는 것은 문제이지만 서비스 로케이터를 가장 명확하게 정의하는 "문제"는 아닙니다.
Sam

1
With dependency injection (at least constructor injection) the dependencies are explicit.. 설명 해주십시오.
FindOutIslamNow

위에서, 나는 ... SL은 DI보다는 의존성이 적은 명시하게 볼 수 없습니다
마이클 Powłoka

38

마틴 파울러 주 :

서비스 로케이터를 사용하면 응용 프로그램 클래스는 로케이터에게 메시지를 통해 명시 적으로 요청합니다. 주입을 통해 명시적인 요청이 없으면 서비스가 응용 프로그램 클래스에 표시되므로 제어가 반전됩니다.

간단히 말해서 : 서비스 로케이터 및 종속성 주입은 종속성 반전 원리의 구현 일뿐입니다.

중요한 원칙은“콘크리트가 아닌 추상화에 의존”입니다. 이렇게하면 소프트웨어 디자인이“느슨하게 결합”,“확장 가능”,“유연”하게됩니다.

필요에 가장 적합한 것을 사용할 수 있습니다. 의존성 주입은 코드베이스에 더 많은 변경이 필요하기 때문에 큰 코드베이스가있는 큰 응용 프로그램의 경우 Service Locator를 사용하는 것이 좋습니다.

이 게시물을 확인할 수 있습니다 : 종속성 반전 : 서비스 로케이터 또는 종속성 주입

또한 고전 : 제어 컨테이너의 반전 및 Martin Fowler의 의존성 주입 패턴

Ralph E. Johnson & Brian Foote의 재사용 가능한 클래스 디자인

그러나 내 눈을 뜨게 한 것은 ASP.NET MVC : Resolve 또는 Inject? 이것이 문제입니다… Dino Esposito의


환상적인 요약 : "서비스 로케이터 및 의존성 주입은 단지 의존성 역전 원리의 구현입니다."
Hans

그리고 그는 또한 다음과 같이 언급합니다. 주요 차이점은 서비스 로케이터를 사용하면 서비스의 모든 사용자가 로케이터에 종속된다는 것입니다. 로케이터는 다른 구현에 대한 종속성을 숨길 수 있지만 로케이터를 볼 필요가 있습니다. 로케이터와 인젝터 간의 결정은 해당 종속성이 문제인지 여부에 달려 있습니다.
프로그램 :

1
ServiceLocator와 DI는 "DIP (Dependency Inversion Principle)"와 관련이 없습니다. DIP는 하위 수준 구성 요소에 대한 컴파일 타임 종속성을 하위 수준 구성 요소와 함께 정의 된 추상 유형에 대한 종속성으로 대체하여 고급 구성 요소를 더 재사용 가능하게 만드는 방법입니다. 레벨 구성 요소; 이런 식으로 컴파일 타임 종속성이 반전됩니다. 이제 상위 레벨에 의존하는 하위 레벨이므로 컴파일 타임 종속성이 반전됩니다. 또한 Martin Fowler의 기사는 DI와 IoC가 같은 것이 아니라고 설명합니다 .
Rogério

23

생성자 DI를 사용하는 클래스는 만족할 종속성이 있음을 코드를 소비 함을 나타냅니다. 클래스가 내부적으로 SL을 사용하여 이러한 종속성을 검색하는 경우 소비 코드는 종속성을 인식하지 못합니다. 이것은 표면적으로는 더 좋아 보일지 모르지만, 명시적인 종속성을 아는 것이 실제로 도움이됩니다. 건축 적 관점에서 더 좋습니다. 또한 테스트를 수행 할 때 클래스에 특정 종속성이 필요한지 여부를 알고 해당 종속성의 적절한 가짜 버전을 제공하도록 SL을 구성해야합니다. DI를 사용하면 가짜를 전달할 수 있습니다. 큰 차이는 없지만 거기에 있습니다.

DI와 SL은 함께 작동 할 수 있습니다. 공통 종속성 (예 : 설정, 로거 등)의 중앙 위치를 갖는 것이 유용합니다. 이러한 dep를 사용하는 클래스가 있으면 des를 수신하는 "real"생성자와 SL에서 검색하여 "real"생성자로 전달하는 기본 (매개 변수 없음) 생성자를 만들 수 있습니다.

편집 : 물론 SL을 사용하면 해당 구성 요소에 몇 가지 커플 링이 도입됩니다. 이러한 기능의 개념은 추상화를 장려하고 결합을 줄이는 것이므로 아이러니합니다. 문제는 균형을 이룰 수 있으며 SL을 사용해야하는 장소 수에 따라 다릅니다. 위에서 제안한대로 수행하면 기본 클래스 생성자에서만 가능합니다.


흥미 롭습니다! DI와 SL을 모두 사용하고 있지만 두 생성자는 사용하지 않습니다. 가장 지루한 세 개 또는 네 개의 의존성 (설정 등)은 SL에서 즉시 가져옵니다. 다른 모든 것은 생성자 주입됩니다. 조금 추악하지만 실용적입니다.
maaartinus

10

둘 다 IoC의 구현 기술입니다. Inversion of Control을 구현하는 다른 패턴들도 있습니다 :

  • 공장 패턴
  • 서비스 로케이터
  • DI (IoC) 컨테이너
  • 의존성 주입 (생성자 주입, 매개 변수 주입 (필요하지 않은 경우), 인터페이스 주입의 세터 주입) ...

서비스 로케이터와 DI 컨테이너는 더 유사 해 보입니다. 둘 다 컨테이너를 사용하여 종속성을 정의하며, 이는 추상화를 구체적인 구현에 매핑합니다.

가장 큰 차이점은 종속성이 Service Locator에서 클라이언트 코드가 종속성을 요청하는 방법입니다. DI 컨테이너에서 컨테이너를 사용하여 모든 객체를 만들고 종속성을 생성자 매개 변수 (또는 속성)로 주입합니다.


7

마지막 프로젝트에서는 두 가지를 모두 사용합니다. 단위 테스트 가능성을 위해 의존성 주입을 사용합니다. 서비스 로케이터를 사용하여 구현을 숨기고 IoC 컨테이너에 의존합니다. 그리고 그렇습니다! IoC 컨테이너 (Unity, Ninject, Windsor Castle) 중 하나를 사용하면 의존합니다. 오래된 것이거나 어떤 이유로 든 교환을 원할 경우 적어도 컴포지션 루트와 같이 구현을 변경해야 할 수도 있습니다. 그러나 서비스 로케이터는이 단계를 추상화합니다.

어떻게 IoC 컨테이너에 의존하지 않습니까? 나쁘게 포장하거나 Service Locator를 사용하여 IoC 컨테이너를 구성해야합니다. 따라서 서비스 로케이터에게 필요한 인터페이스를 제공하도록 지시하고 해당 인터페이스를 검색하도록 구성된 IoC 컨테이너를 호출합니다.

필자의 경우 프레임 워크 구성 요소 인 ServiceLocator 를 사용 합니다. 그리고 IoC 컨테이너에 Unity 를 사용하십시오 . 나중에 IoC 컨테이너를 Ninject 로 교체 해야하는 경우 Unity 대신 Ninject를 사용하도록 서비스 로케이터를 구성해야합니다. 쉬운 마이그레이션.

다음은이 시나리오를 설명하는 훌륭한 기사입니다. http://www.johandekoning.nl/index.php/2013/03/03/dont-wrap-your-ioc-container/


johandekoning 기사 링크가 깨졌습니다.
JakeJ

6

두 사람이 함께 일한다고 생각합니다.

의존성 주입은 의존 클래스 / 인터페이스를 소비하는 클래스 (일반적으로 생성자)로 푸시한다는 것을 의미합니다. 이것은 인터페이스를 통해 두 클래스를 분리하고 소비하는 클래스는 여러 유형의 "주입 종속성"구현에서 작동 할 수 있음을 의미합니다.

서비스 로케이터의 역할은 구현을 통합하는 것입니다. 프로그램 시작시 부팅 스트래핑을 통해 서비스 로케이터를 설정합니다. 부트 스트랩은 구현 유형을 특정 추상 / 인터페이스에 연결하는 프로세스입니다. 런타임에 생성됩니다. (구성 또는 부트 스트랩 기반). 의존성 주입을 구현하지 않았다면 서비스 로케이터 또는 IOC 컨테이너를 사용하기가 매우 어려울 것입니다.


6

추가해야 할 이유 중 하나는 지난 주에 MEF 프로젝트를 위해 작성한 문서 업데이트에서 영감을 얻은 것입니다 (MEF 구축을 도와줍니다).

앱이 잠재적으로 수천 개의 구성 요소로 구성되면 특정 구성 요소를 올바르게 인스턴스화 할 수 있는지 여부를 결정하기가 어려울 수 있습니다. "올바로 인스 트루먼 테이션 됨"은이 예제에서 Foo구성 요소 를 기반으로 하는 인스턴스를 IBar사용할 수 있으며 구성 요소를 제공하는 구성 요소는 다음을 의미합니다.

  • 필요한 의존성을 가지고
  • 잘못된 종속성주기에 관여하지 않으며
  • MEF의 경우 하나의 인스턴스 만 제공됩니다.

두 번째 예제에서 생성자가 종속성을 검색하기 위해 IoC 컨테이너로 이동하는 경우 실제Foo 인스턴스 구성을 사용하여 인스턴스를 올바르게 인스턴스화 할 수 있는지 테스트 할 수있는 유일한 방법 은 실제로 구성하는 것입니다. 그것 .

런타임에 작동하는 코드가 테스트 하네스에서 반드시 작동하지는 않기 때문에 테스트시 모든 종류의 부수적 인 부작용이 있습니다. 실제 구성은 테스트 시간 설정이 아니라 테스트해야 할 것이기 때문에 Mocks는하지 않습니다.

이 문제의 근원은 @Jon에 의해 이미 불려지는 차이점입니다. 생성자를 통한 의존성 주입은 선언적이며 두 번째 버전은 명령형 서비스 로케이터 패턴을 사용합니다.

IoC 컨테이너는주의해서 사용하면 실제로 관련된 구성 요소의 인스턴스를 만들지 않고도 앱의 런타임 구성을 정적으로 분석 할 수 있습니다. 많은 인기있는 컨테이너는 이것의 변형을 제공합니다. .NET 4.5 웹 및 Metro 스타일 앱을 대상으로하는 MEF 버전 인 Microsoft.CompositionCompositionAssert 은 위키 문서에서 샘플을 제공합니다 . 이를 사용하여 다음과 같은 코드를 작성할 수 있습니다.

 // Whatever you use at runtime to configure the container
var container = CreateContainer();

CompositionAssert.CanExportSingle<Foo>(container);

( 이 예제 참조 ).

테스트 시간에 애플리케이션 의 컴포지션 루트 를 확인하면 나중에 프로세스에서 테스트를 통해 미끄러질 수있는 일부 오류를 포착 할 수 있습니다.

이것이 주제에 대한 포괄적 인 답변 세트에 흥미로운 추가 내용이기를 바랍니다.


5

참고 : 나는 정확하게 질문에 대답하지 않습니다. 그러나 이것이 Service Locator (anti-) 패턴 과 혼동되는 Dependency Injection 패턴의 새로운 학습자에게 유용 할 수 있다고 생각합니다. 이것은이 페이지에서 우연히 발생 .

Service Locator (지금은 안티 패턴으로 간주됩니다)와 Dependency Injection 패턴의 차이점을 알고 각 패턴의 구체적인 예제를 이해할 수 있지만 생성자 내부에 서비스 로케이터를 보여주는 예제와 혼동되었습니다 ( 생성자 주입을 다시 수행).

"서비스 로케이터"는 종종 패턴의 이름과 새로운 연산자를 사용하지 않고 객체를 얻기 위해 해당 패턴에 사용 된 객체를 참조하는 이름으로도 사용됩니다. 이제 동일한 유형의 객체를 컴포지션 루트 에서 사용하여 종속성 주입을 수행 할 수 있으며, 이로 인해 혼란이 발생합니다.

요점은 DI 생성자 내에서 서비스 로케이터 객체를 사용하고 있지만 "서비스 로케이터 패턴"을 사용하고 있지 않다는 것입니다. 그것들이 본질적으로 동일한 일을한다고 추측했을 수도 있기 때문에 대신 IoC 컨테이너 객체로 언급하면 ​​혼란스럽지 않습니다 (잘못되면 나를 수정하십시오).

그것이 서비스 로케이터 (또는 단지 로케이터) 또는 IoC 컨테이너 (또는 단지 컨테이너)로 지칭되는지 여부는 아마도 동일한 추상화를 참조하고 있기 때문에 추측 할 때 아무런 차이가 없습니다 (잘못되면 정정하십시오) ). 서비스 로케이터라고 부르는 것은 의존성 주입 패턴과 함께 Service Locator 안티 패턴을 사용하고 있음을 나타냅니다.

IMHO는 'location'또는 'locating'대신 'locator'라는 이름을 지정하여 기사의 서비스 로케이터가 서비스 로케이터 (anti-) 패턴이 아니라 서비스 로케이터 컨테이너를 참조한다고 생각할 수도 있습니다. 특히 의존성 인젝터가 아닌 의존성 주입이라는 관련 패턴이있을 때.


4

이 지나치게 단순화 된 경우에는 차이가 없으며 서로 바꿔 사용할 수 있습니다. 그러나 실제 문제는 그렇게 간단하지 않습니다. Bar 클래스 자체에 D라는 다른 종속성이 있다고 가정하십시오.이 경우 서비스 로케이터는 해당 종속성을 해결할 수 없으므로 D 클래스 내에서 인스턴스화해야합니다. 의존성을 인스턴스화하는 것은 클래스의 책임이기 때문입니다. D 클래스 자체에 다른 종속성이 있으면 실제 상황에서는 일반적으로 그보다 훨씬 복잡해집니다. 이러한 시나리오에서 DI는 ServiceLocator보다 더 나은 솔루션입니다.


4
흠 동의하지 않습니다. 서비스 로케이터 ex. 서비스 로케이터라는 여전히 의존성이 있음을 분명히 보여줍니다. bar클래스 자체에 종속성이 있으면 barDI / IoC 사용의 요점 인 서비스 로케이터도 있습니다.
GFoley83

2

Dependency Injection과 Service Locator의 차이점은 무엇입니까? 두 패턴 모두 종속성 반전 원칙을 구현하는 데 능숙합니다. 서비스 로케이터 패턴은 공용 인터페이스를 변경하지 않고도 전체 설계를 느슨하게 만들므로 기존 코드베이스에서 사용하기가 더 쉽습니다. 같은 이유로 Service Locator 패턴을 기반으로하는 코드는 Dependency Injection을 기반으로하는 동등한 코드보다 읽기 어렵습니다.

의존성 주입 패턴은 클래스 (또는 메소드)가 의존하는 서명을 명확하게합니다. 이러한 이유로 결과 코드는 더 깨끗하고 읽기 쉽습니다.


1

간단한 개념에 따라 Service Locator와 DI 컨테이너의 차이점을 명확하게 이해할 수있었습니다.

  • 서비스 로케이터 는 소비자에서 사용 되며 직접 소비자의 요청에 따라 일부 스토리지에서 ID별로 서비스를 가져옵니다.

  • DI 컨테이너 는 외부 어딘가에 있으며 일부 스토리지에서 서비스를 가져와 소비자에게 푸시 합니다 (생성 자나 메소드를 통해)

그러나 구체적인 소비자 사용 상황에서만 이러한 차이점에 대해 이야기 할 수 있습니다. 서비스 로케이터 및 DI 컨테이너가 컴포지션 루트에 사용되는 경우 거의 비슷합니다.


0

DI 컨테이너는 서비스 로케이터 의 상위 집합 입니다. 의존성 주입을 어셈블 링 (배선)하는 추가 기능을 사용하여 서비스찾는 데 사용할 수 있습니다 .


-2

기록을 위해

//Foo Needs an IBar
public class Foo
{
  private IBar bar;

  public Foo(IBar bar)
  {
    this.bar = bar;
  }

  //...
}

실제로 인터페이스가 필요하지 않은 경우 (인터페이스가 둘 이상의 클래스에서 사용됨) IT를 사용해서는 안됩니다 . 이 경우 IBar는이를 구현하는 모든 서비스 클래스를 활용할 수 있습니다. 그러나 일반적으로이 인터페이스는 단일 클래스에서 사용됩니다.

인터페이스를 사용하는 것이 좋지 않은 이유는 무엇입니까? 정말 디버깅하기 어렵 기 때문입니다.

예를 들어 인스턴스 "bar"가 실패했다고 가정 해 봅시다. 질문 : 어떤 클래스가 실패 했습니까? 어떤 코드를 수정해야합니까? 간단한 견해는 인터페이스로 연결되며 여기가 내 도로가 끝나는 곳입니다.

대신 코드가 엄격한 종속성을 사용하면 실수를 쉽게 디버깅 할 수 있습니다.

//Foo Needs an IBar
public class Foo
{
  private BarService bar;

  public Foo(IBar bar)
  {
    this.bar = bar;
  }

  //...
}

"bar"가 실패하면 BarService 클래스를 확인하고 실행해야합니다.


1
클래스는 특정 객체를 구성하기위한 청사진입니다. 반면에 인터페이스는 contract동작이며 동작이 아닌 동작을 정의합니다. 실제 객체를 전달하는 대신 소비자 만 객체의 나머지 부분에 액세스 할 수 없도록 인터페이스 만 공유됩니다. 또한 단위 테스트의 경우 테스트해야 할 부분 만 테스트하는 데 도움이됩니다. 시간이 지나면 그 유용성을 이해할 것입니다.
Gunhan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.