값을 대체 연관 배열 PHP
-
20-09-2019 - |
문제
(이 질문을 사용하 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
}
배열에 대한 장점이 거의 없습니다.
- 오타를 만들 가능성이 없습니다.
$data['firtsname'] = 'Chris';
잠시 동안 작동합니다$data->setFirtsname('Chris');
EN 오류를 던질 것입니다. 유형 힌트 : 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()); }
유효성 검사 또는 로깅과 같은 설정/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;
- 상속, 다형성, 유형 힌트, 캡슐화 등과 같은 OOP의 모든 이점을 사용할 수 있습니다.
- 앞서 언급 한 바와 같이, 우리의 모든 "structs"는
Countable
,Serializable
또는Iterator
인터페이스, 그래서 우리의 스트러크가 사용할 수 있습니다foreach
루프 등 - 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']
당신은하지 않을 것입니다.