2010-08-11 2 views
2

나는 OOP에 들어가고 다음과 같은 딜레마를 겪는다. 저는 수업을 가지고 있습니다 :각 공용 속성에 접근 자 메서드가 있어야합니까?

class Recipe { 

    var $title; 
    var $time; 
    var $ingredients = array(); 
    var $instructions; 
    var $category; 

    function __construct($title, $time, $ingredients, $instructions, $category) { 

     $this->title = $title; 
     ... 
    } 

    function getTitle() { 
     return $this->title; 
    } 

} 

모든 속성은 공개 (기본값)입니다. 나는 이러한 모든 속성 (예 : 인 getTitle)에 대한 접근 방법을 정의하거나 그냥 같이 직접 속성을 참조 할 수 있습니다 수행

... 
$recipe = new Recipe($title, $time, $ingredients, $instructions, $category); 
echo $recipe->title; // versus $recipe->getTitle(); 

나는 접근 방법을 정의 할 필요가없는 많은 시간을 절약 할 것 같습니다 . 그러나 이런 종류의 접근 방식의 장단점은 무엇일까?

답변

3

공개 속성에는 getter/setter 메서드가 필요하지 않지만 오류가 발생하기 쉽습니다. 접근자를 사용하면 데이터에 대한 유효성 검사를 수행 할 수있는 반면 공용 속성을 직접 설정하면 모든 데이터를 설정할 수 있습니다.

PHP의 마법 함수를 이용하는 경우 개인/보호 된 속성에 액세스하기위한 동적 getter/setter 메서드를 작성할 수 있습니다.

<?php 


/** 
* Implements auto get/set 
* class Entity extends GetterSetter {} 
* $name = $entity->getName(); // return $this->name; 
* $name = $entity->getFullName(); // return $this->full_name; 
* $entity->setFullName("Ian"); // $this->full_name = "Ian"; 
*/ 

class GetterSetter { 
    public function __call($name, $args) { 
     if (substr($name, 0, 3) == "get") { 
      $key = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', (substr($name, 3, strlen($name)-3)))); 
      if (property_exists($this, $key)) { 
       //print "/* GET " . $this . "->" . $key . " = " . $this->$key . "\n */"; 
       return $this->$key; 
      } 
     } elseif (substr($name, 0, 3) == "set") { 
      $key = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', (substr($name, 3, strlen($name)-3)))); 
      if (property_exists($this, $key)) { 
       //print "/* SET " . $this . "->" . $key . " = " . $args[0] . "\n */"; 
       return ($this->$key = $args[0]); 
      } else { 
       print "Key not found: " . $this . "->" . $key; 
      } 
     } 
    } 

} 
?> 
+0

어떤 종류의 오류가 있습니까? 값을 어기는거야? – Michael

+2

임의 데이터를 설정하지 않아도 유효성 검사를 수행하고 오류를 줄일 수 있습니다. –

+0

대신 ** __ get ** 및 ** __ set **을 사용할 수 없습니까? – Michael

4

OOP의 황금 규칙은 항상 당신의 재산 비공개 입니다! 공공 장소가 허용되는 경우는 거의 없지만 대체 솔루션이있을 수도 있습니다.

이유는 : 공개 속성을 공개하면 누구나 원하는대로 변경할 수 있습니다. 대부분의 속성은 어떤 값일 수 없습니다. $ title 속성이 정수 여야합니까? 나는 그것을 의심한다. 그래서 당신이나 다른 누군가 실수로 그것을 정수로 설정한다면 어떨까요? 너는 그것을 발견하지 못할 것이다. 값을 설정하면 문자열이 어딘가에서 예상되므로 프로그램이 실패 할 때까지 프로그램이 계속됩니다. 또한 귀하의 부동산은 설정되기 전에 어떤 방식 으로든 검증되어야합니다. 당신은이 세팅을 부동산 세터에 포함시킬 것입니다.

속성을 확인할 필요가없는 경우에도 결국 확인해야 할 경우를 대비하여 getter 및 setter 뒤에 배치하는 것이 가장 좋습니다.

속성을 비공개로 설정하면 개체가 비어서는 안되는 상황에서 개체가 흩어지지 않도록 할 수 있습니다. :)

때로는 "글쎄, 내 코드 만 편집하므로 아무 일도 일어나지 않을 것"이라고 생각하는 경우가 있습니다. 그러나 지금은 그것을 연습해야합니다. 그것을하는 습관을하십시오. 나중에 문제를 피할 수 있습니다. 게터/세터와

+1

이것은 많은 의미가 있습니다! 그렇다면 PHP에서 기본적으로 모든 속성은 공개로 설정되고 개인 설정이 아닌 이유는 무엇입니까? – Michael

+0

나는 모든 방법 앞에 "public"을 붙이지 않아도되기 때문에 먼저 추측합니다. 또한 공개적으로 유지해야하는 호환성 문제가있을 수 있습니다. 비록 내가 왜 그들이 공개적으로 정확하게 공개되는지에 대한 문서를 찾지 못하는 것 같습니다. C++에서 속성은 기본적으로 private입니다. 특정 언어를 사용하기 시작할 때 어떤 방법인지 알고 있는지 확인하십시오. :) –

+2

[PHP5-OO OO] (http://us3.php.net/manual/en/oop5.intro.php)에 접근성 키워드가 포함되어 있습니다. 현재 스타일은 PHP4 시대이며, 누구도 새로운 코드에 사용해야하지 않습니다. – Charles

2

:

  • 당신은 구현을 변경할 수 있습니다. 예를 들어 나중에 getTime을 변경하여 멤버에게 $ 시간을주지 않고 $ 명령어 수를 계산할 수 있습니다.
  • 세터는 예외를 발생 입력 또는 새로운 상태를 확인, 다른 데이터를 변경, 로그, ... 다른 객체를 사용하거나 무엇을해야 할 것이다 방법과 같은 개체의

생각할 수 있습니다. 객체는 데이터 유형 목록 이상입니다.

4

PHP에서 특히 불필요한 setter/getters를 사용해서는 안되며, 응용 프로그램이 상당히 느려질 수 있습니다.

<?php 
class Recipe { 

    public $title; 

    function __construct($title){ 
     $this->title = $title; 
    } 

    function getTitle(){ 
     return $this->title; 
    } 

} 

$a = new Recipe('potatoes'); 
$t1 = microtime(true); 
for($i=0;$i<1000000;$i++){ 
    $x = $a->title; 
} 
$t2 = microtime(true) - $t1; 
echo $t2.'s<br/>'; 

$a = new Recipe('potatoes'); 
$t1 = microtime(true); 
for($i=0;$i<1000000;$i++){ 
    $x = $a->getTitle(); 
} 
$t2 = microtime(true) - $t1; 
echo $t2.'s<br/>'; 

?> 

에코 : 게터와 느린

0.25662112236023s

1.0309250354767s

4 번 여기서 간단한 예이다!

+0

코드를 올바르게 이해한다면 다른 방법이 될 것입니다 ... getter로 4 배 빠릅니다. – Michael

+0

죄송합니다. 잘못된 순서로 결과를 복사하여 내 게시물을 편집하게하고 직접 테스트 해보십시오. :) – darma

4

Getter/Setters는 대부분의 스크립팅 언어에서 눈살을 찌푸리게합니다. 그들은 원래 Java와 Java Beans로 처음 소개되었습니다. 강력한 캡슐화는 정적으로 컴파일 된 코드에서 의미가 있습니다. 스크립팅 언어에서 모든 액세스는 메모리 주소로 직접 전달되는 것이 아니라 어쨌든 통역사를 통해 이루어집니다. 그러므로 마술 방법이 있습니다. PHP에서는 __get을 통해 모든 것을 라우팅 할 수 있으므로 래퍼가 중복됩니다.

getter/setters의 유스 케이스는 입니다. 필터링 및 유효성 검사 스키마는입니다. 구체적인 속성을 생각해 내지 않으면 중공의 setter를 준비하는 것은 의미가 없습니다 (getter는 거의 값을 변환하지 않습니다).

관련 문제