2015-01-19 5 views
0

의 고려 나쁜 :PHP, 왜 Demeter의 법을 어기는 것이 그렇게 나쁜가요? 내가 아는

$this->laptop->getKeyboard()->getTouchpad()->getLbutton(); 

또는 "우리는 톤 돼요 -> -> -> ->"-로 설명

$this->laptop->getKeyboard()->getCapslock()->isLedOn(); 

하지만이 건설 신체를 만들고 싶었다 , 그것은 분리 될 수 없다는 뜻입니다. 건축가가 바뀌면 모든 일이 이루어져야하지만 그 일은 일어나지 않을 것이라는 것을 이해합니다. 그럼 다시,이 문제를 해결하는 방법?

+1

LoD는 메서드 호출이 아니라 개체의 멤버 변수에 액세스하는 것을 의미한다고 생각합니다. 'a-> b-> c-> d '는 많이 가져서는 안되지만'a-> b() -> c() -> d()'는 괜찮습니다. – Barmar

+1

getLbutton을 반환하는 함수를 가지고 있지 않습니까? 예. $ this-? laptop-> getLButton(); - 설정되지 않은 경우 NULL을 반환합니다. ?? –

+1

@Barmar'a-> b() -> c() -> d()'도 나쁘다. 내 대답을 보라. – woru

답변

6

법칙은 약 의존성이 아닙니다 -> (또는 다른 언어의 점).

예를 들어 유창한 인터페이스 (메소드가이를 반환하는 경우)는이 법률이 적용되지 않습니다.

클래스가 다른 클래스의 최소 수에 의존하기를 원합니다.

클래스가 다른 10 개의 클래스에 의존하는 경우, 클래스가 변경되면 클래스가 변경 될 수 있습니다. 수업이하는 일을 이해하는 것이 어렵습니다. 그런 수업을 시험하는 것도 어렵습니다.

$field->getDependency1()->getDependency2() 또는 $field->dependency1->dependency2이있는 경우 문제가되지 않습니다. 코드는 여전히 다른 두 클래스에 의존하며 dependency1의 내부 구조 (내부에 dependency2가 있음)를 알고 있습니다.

tell don't ask principle으로 문제를 해결할 수 있습니다. OOD에서 데이터를 보유하고있는 구조 만 사용하고 싶지는 않습니다. 당신은 자신의 들판에서해야 할 일을 알고있는 물건을 갖고 싶습니다.

예를 들어, 당신은 리팩토링 할 수

$oldBalance = $bank->getAccount()->getBalance(); 
$bank->getAccount()->setBalance($oldBalance - $amount); 

에 :

$bank->withdraw($amount); 

은행 클래스 :

function withdraw($amount) { 
    $this->account->withdraw($amount); 
} 

계정 클래스에서 :

function withdraw($amount) { 
    $this->balance = $this->balance - $amount; 
} 

더 많은 방법이 있지만 $ bank를 사용하는 코드는 계정 및 잔액에 대해 아무것도 모릅니다. $ bank 필드 만 조롱하는 클래스를 쉽게 테스트 할 수 있습니다. 또한 재사용 가능한 코드가 더 있습니다.

You: Hey Laptop, get me the I/O devices 
Laptop: There you go 
You: Hey IODevices, get me the keyboard 
IODevices: There you go 
You: Hey Keyboard, get me the touchpad 
Keyboard: There you go 
You: Hey Touchpad, I want to press your left button 
Touchpad: Consider it done Boss! 

남자, 당신은 전자 팬보이를 괴물이있어, 또는 당신은 생계를 위해 그것을 할 - 당신은 노트북의 모든 작은 조각을 알고

6

이 대화를 상상해보십시오! ;)

대이 :

후드 번째 대화에서
You: Hey Laptop, I want to press left button on the touchpad 
// Laptop gets the job done 
Laptop: Done Boss! 

,

  1. Laptop

  2. IODevices
  3. 는 의존성을 호출 (당신은 그것에 대해 아무것도 알 필요가 없습니다) 의존성 IODevices를 호출 Keyboard ( Latop은 그것에 대해 알 필요가 없습니다.)
  4. Keyboard은 종속성을 얻습니다. Touchpad (IODevices은 그것에 대해 알 필요가 없습니다. 실제로 이것은 약간 나쁜 예입니다. 그러나 ... 당신은 아이디어를 얻습니다.) 그리고 나서 pressLeftButton()을 호출하십시오.

즉, 사용자가 세부 사항에 대해 신경 쓰지 않는다면, 사용자가 원하는 것은 pressLeftButton입니다. KeyboardTouchpad이 어떻게 관련되는지, 각 메소드에서 반환되는 것을 알 필요는 없습니다. 구현해야하는 공용 인터페이스가 있습니다.

KeyboardXyzKeyboardAbc으로 바꾸면 아무 것도 깨지지 않으므로 모두가 행복합니다. 후자가 동일한 인터페이스를 구현하는 한.