태그 보관물: object-oriented

object-oriented

PHP에 왜 인터페이스가 있습니까? 인터페이스가 언어에 추가되었습니다.

PHP5부터 인터페이스가 언어에 추가되었습니다. 그러나 PHP는 너무 느슨하게 입력 되었기 때문에 인터페이스 사용의 이점이 대부분 손실되는 것 같습니다. 왜 언어에 포함되어 있습니까?



답변

PHP에서 인터페이스의 주요 장점은 클래스가 여러 인터페이스를 구현할 수 있다는 것입니다. 이를 통해 일부 기능을 공유하지만 부모 클래스를 반드시 공유 할 필요는없는 클래스를 그룹화 할 수 있습니다. 일부 예에는 특정 방식으로 클래스의 캐싱, 출력 또는 액세스 속성이 포함될 수 있습니다.

코드에서 클래스 이름을 확인하는 대신 클래스가 지정된 인터페이스를 구현하는지 확인할 수 있습니다. 그런 다음 새 클래스를 추가해도 코드가 계속 작동합니다.

PHP는 http://php.net/manual/en/reserved.interfaces.php 와 같은 다양한 상황에서 유용 할 수있는 미리 정의 된 인터페이스를 제공합니다 .

편집-예제 추가

MyInterface라는 인터페이스가 있고 일부 기능을 공유하거나 공유하지 않을 수있는 다른 클래스의 여러 객체로 작업하는 경우 인터페이스를 통해 다음과 같은 작업을 수행 할 수 있습니다.

// Assume $objects is an array of instances of various classes
foreach($objects as $obj) {
 if($obj instanceof MyInterface) {
     $obj->a();
     $obj->b();
     $obj->c();
   }
}


답변

PHP는 느슨하게 입력되었지만 메소드 매개 변수와 같은 것에 대해서는 강력하게 입력 할 수 있습니다.

다음 예제를 고려하십시오.

interface Car { function go(); }

class Porsche { function go() {} }

function drive(Car $car) {}

$porsche = new Porsche();

drive($porsche);

위의 코드는 다음과 같이 출력됩니다.

drive ()에 전달 된 인수 1은 주어진 Cars, Porsche의 인스턴스를 구현해야합니다.


답변

인터페이스를 사용하면 개방 폐쇄 원칙을 구현하고 느슨하게 결합 된 코드 기반을 유지하며 최고의 OOP 디자인 패턴을 구현할 수 있습니다.

예를 들어, 한 클래스가 다른 클래스를 인수로 허용하는 경우 :

class A {

    public function __construct(B $class_b) {
        // use class b
        $class_b->run();
    }
}

클래스 A와 클래스 B는 이제 밀접한 결합을 가지며 클래스 A는 B를 제외한 다른 클래스를 사용할 수 없습니다. 유형 힌트는 올바른 유형의 인수를 갖지만 이제 A와 B 사이의 관계를 강화했습니다.

그러나 클래스 A가 run () 메소드를 가진 모든 유형의 클래스를 사용할 수 있기를 원한다고 가정 해 봅시다. 이것은 기본적으로 COMMAND 디자인 패턴입니다. 해결하려면 콘크리트 클래스 대신 인터페이스를 사용하여 힌트를 입력하십시오. B는 해당 인터페이스를 구현하고 클래스 A의 인수로 허용됩니다.이 방법으로 클래스 A는 해당 인터페이스를 생성자에 대한 인수로 사용하는 모든 클래스를 승인 할 수 있습니다.

이 유형의 코딩은 대부분의 OOP 디자인 패턴에 사용되며 나중에 더 쉽게 코드를 변경할 수 있습니다. 이들은 AGILE 프로그래밍의 기본 사항 중 일부입니다.


답변

@pjskeptic에는 좋은 대답 이 있으며 @Kamil Tomšík는 그 대답에 대해 좋은 의견을 가지고 있습니다.

PHP와 같이 동적으로 유형이 지정된 언어의 가장 큰 장점은 객체에 메소드를 사용하려고 시도 할 수 있으며 메소드가 없으면 소리 지르지 않는다는 것입니다.

PHP와 같이 동적으로 유형이 지정된 언어의 문제는 객체에서 메소드를 사용하려고 시도 할 수 있으며 메소드가 없을 때 소리를 지르는 것입니다.

인터페이스는 알 수없는 객체에서 메소드를 호출하고 메소드가 있는지 확인하는 편리한 방법을 추가합니다 (정확히 작동하거나 작동하지는 않음). 언어의 필수 부분은 아니지만 코딩이 더 편리합니다. 강력하게 형식화 된 OOP 개발자는 강력하게 형식화 된 PHP 코드를 작성하여 다른 PHP 개발자가 작성한 느슨하게 형식화 된 PHP 코드와 함께 작동 할 수 있습니다.

다음과 같은 기능 :

foo( IBar $bar )
{
  $baz = $bar->baz();
  ...
}

보다 편리합니다 :

foo( $bar )
{
  if ( method_exists( $bar, 'baz' ) )
  {
    $baz = $bar->baz();
  }
  else
  {
    throw new Exception('OMGWTF NO BAZ IN BAR!');
  }
  ...
}

IMHO 간단하고 읽기 쉬운 코드가 더 나은 코드입니다.


답변

오리 타이 퍼 인 경우 완전히 쓸모가 없습니다. 실제로 오리 타이핑을 할 때 모든 유형 힌트를 사용하는 라이브러리 / 프레임 워크로 작업하는 것은 꽤 성가신 일입니다.

이는 모든 종류의 동적 메타 프로그래밍 (마법 방법)에도 적용됩니다.


답변

PHP는 하지 느슨하거나 강하게,하지만 동적으로 입력 .

인터페이스에 대해 가장 먼저 알아야 할 것은 인터페이스의 장점이 무엇입니까?

OOP에서 인터페이스는 유형뿐만 아니라 동작에 관한 것입니다.

PHP에는 또한 유형 힌트 기능 이 있으므로 Java와 같은 순수한 oo 언어에서와 마찬가지로 인터페이스를 사용할 수 있습니다.

interface File
{
    public function getLines();
}

CSVFile implements File
{
    public function getLines()
    {}
}

XMLFile implements File 
{
    public function getLines()
    {}
}

JSONFile implements File 
{
    public function getLines()
    {}
}

class FileReader
{
    public function read(File $file)
    {
        foreach($file->getLines() as $line)
        {
            // do something
        }
    }
}

PHP 인터페이스 구현을 사용하면 PHPUnit을 사용하여 추상 클래스에 대한 모의 객체를 만들 수도 있습니다. 이것은 기능의 지옥입니다.

public function testSomething()
{
    $mock = $this->getMockForAbstractClass('File');

    $mock->expects($this->once())
         ->method('getLines')
         ->will($this->returnValue(array()));

    // do your assertions
}

따라서 기본적으로 언어 기능 (인터페이스 중 하나)을 사용하여 PHP에서 SOLID 호환 응용 프로그램 을 사용할 수 있습니다 .


답변

인터페이스는 콘크리트보다 의존성 주입에 훨씬 유용합니다. 베어 본 예제로 :

interface Istore { 
  public function save(); 
}

class Article_DB implements Istore 
{ 
  public function save($data) 
  {
    // do save to format needed.
  } 
}

class Article
{
   private $content;

   public function content($content)
   {
     $this->content = $content;
   }

   public function save(Istore $store)
   {
     $store->save($this->content);
   }
}

$article = new Article();
$article->content('Some content');

$store = new Article_DB();
$article->save($store);

이제 필요가 바뀌고 PDF로 저장하고 싶다고 말하십시오. Article 클래스를 오염시키는 대신 해당 목적을 위해 새로운 클래스를 만들 수 있습니다.

class Article_PDF implements Istore 
{ 
  public function save($data) 
  {
    // do save to format needed.
  } 
}


$article = new Article();
$article->content('Some content');

$store = new Article_PDF();
$article->save($store);

Article 클래스에는 이제 저장하기 위해 사용하는 클래스가 Istore 인터페이스를 구현해야하는 계약이 있습니다. 저장 위치 또는 저장 방법은 중요하지 않습니다.