소행성이야기

[part 3] PHP로 좋은 객체 지향(OOP) 습관을 가집시다. 부제: 메두사를 바라 보지 마라

소행성왕자 2018. 7. 9. 09:01

[part 3] PHP로 좋은 객체 지향(OOP) 습관을 가집시다. 

부제: 메두사를 바라 보지 마라



OO 개념을 처음 배울 때 인터페이스가 정말 도움이되었는지 의심스러웠습니다.

머 아직도 계속 공부중이구요.

어떤분은 인터페이스를 사용하지 않는 것이 메두사의 머리를 보는 것과 같은 비유를 이끌어 냈습니다.

그리스 신화에서 메두사는 머리카락에 뱀이있는 여성 캐릭터였습니다.


그녀를 직접 본 사람은 돌로 변했습니다.

메두사를 죽인 페르세우스는 자신의 방패를 들여다 보면서 그녀와 마주 할 수 있었고 돌로 변하는 것을 피할 수 있었습니다.


인터페이스는 메두사를 다루는 당신의 거울입니다.

구체적이고 구체적인 구현을 사용하면 구현 코드가 변경되면 코드가 변경되어야합니다.

구현을 사용하면 본질적으로 클래스를 돌로 만들었 기 때문에 많은 옵션이 직접 제한됩니다.



나쁜 습관 : 인터페이스를 사용하지 않음


Person데이터베이스 에서 객체 를로드하는 예제이다 . 그 사람의 이름이 필요하며 Person 일치하는 데이터베이스 의 객체를 반환합니다 .


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
class DBPersonProvider
{
    public function getPerson($givenName$familyName) {
        $person = new Person();
        $person->setPrefix("Mr.");
        $person->setGivenName("John");
        return $person;
    }
}
 
$provider = new DBPersonProvider();
$person = $provider->getPerson("John""Doe");
 
echo($person->getPrefix());
echo($person->getGivenName());
cs




위 코드는 Person 데이터베이스에서 로드하는 코드는 환경이 바뀔 때까지 괜찮습니다.

예를 들어, Person 응용 프로그램의 첫 번째 버전에서는 데이터베이스에서 로드 하는 것이 좋지만 

두 번째 버전에서는 웹 서비스에서 사람을 로드하는 기능을 추가해야 할 수도 있습니다.


본질적으로 클래스는 구현 클래스를 직접 사용하기 때문에 돌로 변했고 이제는 변경하기가 쉽지 않습니다.



좋은 습관 : 인터페이스 사용


사용자로드의 새로운 방법이 사용 가능해지고 구현 될 때 변경되지 않는 코드의 예를 보여줍니다.

이 예제는 PersonProvider 하나의 메소드를 선언하는 호출 된 인터페이스를 보여줍니다.

어떤 코드에서 a를 사용하면 코드는 PersonProvider구현 클래스를 직접 사용하지 못하게합니다.

대신 PersonProvider 실제 객체인 것처럼 사용합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?php
interface PersonProvider
{
    public function getPerson($givenName$familyName);
}
 
class DBPersonProvider implements PersonProvider 
{
    public function getPerson($givenName$familyName) {
        $person = new Person();
        $person->setPrefix("Mr.");
        $person->setGivenName("John");
        return $person;
    }
}
 
class PersonProviderFactory
{
    public static function createProvider($type) {
        if ($type == 'database') {
            return new DBPersonProvider();
        } 
     else {
            return new NullProvider();
        }
    }
}
 
$config = 'database';
 
$provider = PersonProviderFactory::createProvider($config);
$person = $provider->getPerson("John""Doe");
 
echo($person->getPrefix());
echo($person->getGivenName());
cs



인터페이스를 사용할 때는 직접 구현 클래스를 참조하지 않도록하십시오.

대신, 올바른 구현을 제공하기 위해 객체 외부에 무언가를 사용하세요.

클래스가 일부 로직을 기반으로 구현을 로드하는 경우 모든 구현 클래스의 정의가 필요하므로 어디서나 얻을 수 없습니다.


팩토리 패턴을 사용하여 인터페이스를 구현하는 구현 클래스의 인스턴스를 만들 수 있습니다.

factory 방법은 규칙에 따라, 시작 create 및 인터페이스를 반환합니다.

factory 반환할 올바른 구현 클래스를 파악하는 데 필요한 인수를 취할 수 있습니다.