문제

(이 질문을 사용하 PHP 컨텍스트로만 제한되지 않습니다 PHP 니다.예:어떤 언어를 구축에서는 또한 관련)

을 보자 이를 들어(PHP):

function makeAFredUsingAssoc()
{
    return array(
        'id'=>1337,
        'height'=>137,
        'name'=>"Green Fred");
}

대:

class Fred
{
    public $id;
    public $height;
    public $name;

    public function __construct($id, $height, $name)
    {
        $this->id = $id;
        $this->height = $height;
        $this->name = $name;
    }
}

function makeAFredUsingValueObject()
{
    return new Fred(1337, 137, "Green Fred");
}

방법#1 은 물론 terser,그러나 그것을 쉽게 이끌어 오류 등

$myFred = makeAFredUsingAssoc();
return $myFred['naem']; // notice teh typo here

물론 하나의 주장 할 수 있는 $myFred->naem 이 동등하게로 이끌어 오류가는 사실입니다.그러나 형식적인 클래스 다만 느낌이 더 엄격하게 수는 없지만 정말로 정당화한다.

무엇이 될 것이 장점/단점을 각각 사용하여 접근해야 할 때 사람들이 사용하는 방법?

도움이 되었습니까?

해결책

표면 아래, 두 가지 접근법은 동일합니다. 그러나 캡슐화, 상속 등 클래스를 사용할 때 대부분의 표준 OO 혜택을 얻을 수 있습니다.

또한 다음 예를보십시오.

$arr['naem'] = 'John';

완벽하게 유효하며 찾기 어려운 버그가 될 수 있습니다.

반면에,

$class->setNaem('John');

작동하지 않을 것입니다.

다른 팁

이와 같은 간단한 수업 :

class PersonalData {
    protected $firstname;
    protected $lastname;

    // Getters/setters here
}

배열에 대한 장점이 거의 없습니다.

  1. 오타를 만들 가능성이 없습니다. $data['firtsname'] = 'Chris'; 잠시 동안 작동합니다 $data->setFirtsname('Chris'); EN 오류를 던질 것입니다.
  2. 유형 힌트 : PHP 배열은 모든 것을 포함 할 수 있지만 잘 정의 된 클래스에는 지정된 데이터 만 포함됩니다.

    public function doSth(array $personalData) {
        $this->doSthElse($personalData['firstname']); // What if "firstname" index doesn't exist?
    }
    
    
    public function doSth(PersonalData $personalData) {
        // I am guaranteed that following method exists. 
        // In worst case it will return NULL or some default value
        $this->doSthElse($personalData->getFirstname());
    }
    
  3. 유효성 검사 또는 로깅과 같은 설정/GET 작업 전에 추가 코드를 추가 할 수 있습니다.

    public function setFirstname($firstname) {
        if (/* doesn't match "firstname" regular expression */) {
            throw new InvalidArgumentException('blah blah blah');
        }
    
    
    
    if (/* in debbug mode */) {
        log('Firstname set to: ' . $firstname);
    }
    
    
    $this->firstname = $firstname;
    
    }
  4. 상속, 다형성, 유형 힌트, 캡슐화 등과 같은 OOP의 모든 이점을 사용할 수 있습니다.
  5. 앞서 언급 한 바와 같이, 우리의 모든 "structs"는 Countable, Serializable 또는 Iterator 인터페이스, 그래서 우리의 스트러크가 사용할 수 있습니다 foreach 루프 등
  6. IDE 지원.

유일한 단점은 속도 인 것 같습니다. 배열을 만들고 작동하는 것이 더 빠릅니다. 그러나 우리 모두는 많은 경우 CPU 시간이 프로그래머 시간보다 훨씬 저렴하다는 것을 알고 있습니다. ;)

한동안 그것에 대해 생각한 후, 여기에 내 대답이 있습니다.

가장 중요한 것 가치 객체를 선호합니다 배열 위에 있습니다 명쾌함.

이 기능을 고려하십시오 :

// Yes, you can specify parameter types in PHP
function MagicFunction(Fred $fred)
{
    // ...
}

~ 대

function MagicFunction(array $fred)
{
}

의도는 명확합니다. 기능 저자는 자신의 요구 사항을 시행 할 수 있습니다.

더 중요한 것은 사용자로서 쉽게 찾을 수 있습니다. 유효한 프레드를 구성하는 것. 나는 단지 열 필요가있다 Fred.php 내부를 발견하십시오.

발신자와 칼리 사이에는 계약이 있습니다. 값 객체를 사용 하여이 계약은 구문 확인 코드로 작성할 수 있습니다.

class Fred
{
    public $name;
    // ...
}

배열을 사용한 경우 사용자가 댓글이나 문서를 읽기를 바랍니다.

// IMPORTANT! You need to specify 'name' and 'age'
function MagicFunction(array $fred)
{
}

Usecase에 따라 나는 또는 둘 중 하나를 사용할 수 있습니다. 클래스의 장점은 유형처럼 사용할 수 있다는 것입니다. 쿼리 나 무언가에서 임의의 데이터 세트를 전달하고 싶다면 배열을 사용할 것입니다. 그래서 나는 오래된 것 같아요 프레드 내 모델에 특별한 의미가 있으며, 수업을 사용합니다.

사이드 노트 :
ValueObjects는 불변이되어야합니다. 최소한 도메인 구동 설계에서 Eric Evan의 정의를 언급하는 경우. Fowler의 POEA에서 ValueObjects는 반드시 불변 할 필요는 없지만 (제안되었지만) 신원이 없어야합니다. 프레드.

이 질문을 당신에게 제시하겠습니다.

오타를 좋아하는 것과 다른 점은 무엇입니까? $myFred['naem'] 그리고 오타를 좋아합니다 $myFred->naem? 두 경우 모두 동일한 문제가 여전히 존재하며 둘 다 오류가 발생합니다.

나는 사용하는 것을 좋아한다 키스 내가 프로그램 할 때 (간단하고, 어리석은).

  • 메소드에서 쿼리의 서브 세트를 단순히 반환하는 경우 배열을 반환하십시오.
  • 데이터를 a로 저장하는 경우 공개/개인/정적/보호 수업 중 하나에서 변수는 STDClass로 저장하는 것이 가장 좋습니다.
  • 나중에 이것을 다른 클래스 방법으로 전달하려는 경우, 엄격한 타이핑을 선호 할 수 있습니다. Fred 수업, 즉 public function acceptsClass(Fred $fredObj)

반환 값으로 사용하려면 배열과 달리 표준 클래스를 쉽게 만들 수 있습니다. 이 경우 엄격한 타이핑에 대해 덜 신경 쓸 수 있습니다.

$class = new stdClass();
$class->param = 'value';
$class->param2 = 'value2';
return $class;

프로 해시:그것은 처리할 수 있 이름 값의 조합이있는 알 수 없 디자인다.

반환 값이 응용 프로그램의 엔티티를 나타내는 경우 OOP의 목적이므로 객체를 사용해야합니다. 관련없는 값 그룹을 반환하려면 그렇게 명확하지 않습니다. 그러나 공개 API의 일부라면 선언 된 클래스가 여전히 가장 좋은 방법입니다.

솔직히, 나는 둘 다 좋아합니다.

  • 해시 어레이는 물체를 만드는 것보다 훨씬 빠르며 시간은 돈입니다!
  • 그러나 JSON은 해시 어레이를 좋아하지 않습니다 (OOP OCD와 비슷한 것 같습니다).
  • 어쩌면 여러 사람이있는 프로젝트의 경우 잘 정의 된 수업이 더 좋습니다.
  • 해시 어레이에는 더 많은 CPU 시간과 메모리가 필요할 수 있지만 (객체는 사전 정의 된 금액을 가지고 있음) 모든 시나리오에 대해서는 확신하기가 어렵습니다.

그러나 실제로 짜증나는 것은 어느 것이 너무 많이 사용해야하는지 생각하는 것입니다. 내가 말했듯이, JSON은 해시를 좋아하지 않습니다. 죄송합니다. 배열을 사용했습니다. 나는 지금 몇 천 줄의 코드를 바꿔야했다.

나는 그것을 좋아하지 않지만, 수업은 더 안전한 방법 인 것 같습니다.

적절한 값 객체의 이점은 실제로 유효하지 않은 것을 만들 수있는 방법이 없으며 존재하는 것을 변경할 수있는 방법 (무결성과 불변성)입니다. getters와 type hinting 매개 변수 만 있으면 편집 가능한 코드로 망칠 방법이 없습니다.

또는 공개 생성자에서 검증하고 예외를 던질 수 있지만 이는 온화한 공장 방법을 제공합니다.

class Color
{
    public static function create($name, $rgb) {
        // validate both
        if ($bothValid) {
            return new self($name, $rgb);
        } else {
            return false;
        }
    }
    public function getName() { return $this->_name; }
    public function getRgb() { return $this->_rgb; }

    protected function __construct($name, $rgb)
    {
        $this->_name = $name;
        $this->_rgb = $rgb;
    }
    protected $_name;
    protected $_rgb;
}

저는 10 년 동안 OOP 언어와 함께 일했습니다. 객체가 작동하는 방식을 이해하면 그것을 좋아할 것입니다. 상속, 다형성, 캡슐화, 과부하가 OOP의 주요 장점입니다. 반면에 PHP에 대해 이야기 할 때 PHP는 전체 객체 지향 언어가 아니라는 것을 고려해야합니다. 예를 들어 메소드 오버로드 또는 생성자 오버로드 (직접)를 사용할 수 없습니다.

PHP의 연관 배열은 매우 좋은 기능이지만 PHP 엔터프라이즈 애플리케이션에 해를 끼치는 것으로 생각합니다. 코드를 작성하면 깨끗하고 유지 관리 가능한 응용 프로그램을 원합니다.

또 다른 것은 당신이 연관 배열로 느슨하다고 생각한다고 생각합니다.

따라서 Cleanner 및보다 관리 가능한 코드를 작성하려면 OOP 기능이 제공 될 때 사용해야한다고 생각합니다.

두 번째 예제에서와 같이 하드 코딩 된 속성을 선호합니다. 나는 그것이 예상 클래스 구조 (그리고 클래스의 가능한 모든 속성)를 더 명확하게 정의한다고 생각합니다. 동일한 키 이름을 항상 사용하는 것을 기억하는 첫 번째 예와 반대로. 두 번째로 항상 돌아가서 클래스를보고 파일의 상단을 보면 속성에 대한 아이디어를 얻을 수 있습니다.

두 번째로 잘못하고 있다는 것을 알게 될 것입니다. echo $this->doesntExist 시도하면 오류가 발생합니다 echo array['doesntExist'] 당신은하지 않을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top