2017-04-26 23 views
1

나는 독학 프로그래머이며 현재 Zend Framework 2를 배우고 있습니다.PHP에서 "사용"키워드를 Interface와 함께 사용해야하는 이유는 무엇입니까?

나는 항상 특정 서비스를 포함하려고 할 때마다 항상 인터페이스 버전을 사용해야한다고 생각합니다.

예를 들어, 서비스 로케이터를 사용하려고하면 서비스 로케이터를 사용하기 위해 serviceLocatorInterface을 포함해야합니다. 서비스 로케이터 클래스 자체를 사용할 수없는 이유는 무엇입니까?

여기는 Abstract Factory 클래스에서 가져온 것입니다.

use Zend\ServiceManager\ServiceLocatorInterface; 

은 그 때 나는

use Blog\Service\PostServiceInterface; 

https://framework.zend.com/manual/2.4/en/in-depth-guide/services-and-servicemanager.html#bringing-the-service-into-the-controller 우리는 PostServiceInterface을 포함, 거기에 이런 식으로 여기

public function canCreateServiceWithName(ServiceLocatorInterface $serviceLocator, $name, $requestedName) 

젠드 튜토리얼에서 또 다른 예는 다음을 사용합니다. 왜 PostService가 아닌가?

public function __construct(PostServiceInterface $postService) 

우리는 여기에 PostServiceInterface를 사용합니다. 왜 PostService가 Type이 아닌가?

나는 이것이 모든 학생들이 대답 할 수있는 매우 간단한 대답이지만, 나는 자신을 배우기 때문에 이것을 이해하는 데 어려움을 겪고 있다고 확신한다.

추신. 나는 인터페이스와 상속의 개념을 이해하고있다. 나는 왜 우리가 Interface를이 방법으로 포함시키는 지 모른다.

편집 : 대답 뒤에 사람들이 구체적인 유형 대신 유형 종속성으로 인터페이스를 전달하는 이유를 더 잘 이해하는 데 도움이되는 링크를 찾았습니다.

http://kristopherwilson.com/2015/03/26/using-interfaces-effectively-in-php/

What is the difference between an interface and abstract class?

나는 그 링크를 elses 너무 사람을 도움이되기를 바랍니다.

답변

1

use은 사용 된 클래스 정규화 된 이름의 로컬 별칭을 만듭니다. 클래스 이름은 클래스의 이름이 아니라 항상 정의 된 네임 스페이스를 포함합니다. 당신이 지역의 별칭을 만들 수 use 키워드를 사용하지 않는 경우

는 PHP 클래스는 현재 네임 스페이스에, 가정

(파일의 네임 스페이스를 선언하지 않으면,이 루트 네임 스페이스 \입니다)

간단한 예

// the current namespace 
namespace Foo; 

use Test\ClassName; 

class Bar { 
    public function __construct(Baz $a) { 
     // Baz isn't a full qualified class name (missing leading \), so 
     // php assumes, Baz is inside the current namespace Foo 
     // => full class name is \Foo\Baz; 
    } 

    public function doSomething(ClassName $a) { 
     // ClassName isn't a full qualified class name, BUT there is an use 
     // statement, which imported ClassName to the local file 
     // => \Test\ClassName 
    } 

    public function doSomethingElse(\ClassName $a) { 
     // ClassName IS a full qualifed class name 
     // => \ClassName 
    } 
} 

참고 \ClassName\Test\ClassName 두 가지 종류가있다.


그래서 왜가없는 PostServiceInterface 대신

PostService의 사용하지만, 그것은 많은 혜택을 그렇게 좋은 방법입니다. 나는. 나중에 함수를 테스트하고 PostService이 필요하지 않습니다. PostService에서 상속받은 새 클래스를 만들면 PostService가 final으로 선언 될 수 있기 때문에 좋은 해결책이 아닐 수 있습니다.

이 방법은 다음과 같습니다. 클래스를 사용하지 마십시오. 인터페이스를 매개 변수로 사용하십시오. 이 원칙은 Dependency Inversion Principle라는 SOLID 원칙의 일부이며 두 가지 상태 :

  • 높은 수준의 모듈은 낮은 수준의 모듈에 의존하지 말아야한다. 둘 다 추상화에 의존해야합니다.

  • 추상화는 세부 정보에 의존해서는 안됩니다. 세부 사항은 추상화에 따라 달라져야합니다.

+0

네가 말하는 것은 네임 스페이스가 유형이고 함수에 전달하는 유형입니다. 내가 이해하지 못하는 이유는 인터페이스를 유형으로 전달하는 이유와 클래스를 유형으로 전달하지 않는 이유입니다. –

+0

인터페이스와 클래스 타입 간에는 차이가 없습니다 – Philipp

+0

@TomKoston 인터페이스 'B'를 구현하는 클래스'A '가 있다면, 인터페이스를 함수 param으로 사용합니다. 왜냐하면'A'를 다른 것으로 바꿀 수 있기 때문입니다 (즉, 단위 테스트 용 모의 등). 따라서 단위 테스트 또는 향후 변경을위한 어플리케이션 확장을위한 유연성이 향상됩니다. 형식 매개 변수로'A'를 사용할 수도 있지만 이것은 불필요한 제한입니다 – Philipp