언제 stdClass를 사용해야하고 언제 PHP oo 코드에서 배열을 사용해야합니까?
직장에서 큰 리팩토링 기간 중에 함수에서 데이터를 반환하는 방법으로 stdClass *****를 소개하고 싶습니다. 그리고 내 결정을 뒷받침 할 비 주관적인 인수를 찾으려고합니다.
다른 대신 하나를 사용하는 것이 가장 좋은 상황이 있습니까?
배열 대신 stdClass를 사용하면 어떤 이점이 있습니까?
어떤 사람들은 함수가 하나의 단일 값을 반환 할 수 있으려면 작고 구체적이어야한다고 말합니다. 장기적으로 각 프로세스에 적합한 Value Object를 찾기를 희망하기 때문에 stdClass를 사용하기로 한 결정은 일시적입니다.
일반적인 접근 방식은
고정 분기가있는 정의 된 데이터 구조를 반환 할 때 객체를 사용합니다.
$person -> name = "John" -> surname = "Miller" -> address = "123 Fake St"
목록을 반환 할 때 배열을 사용합니다.
"John Miller" "Peter Miller" "Josh Swanson" "Harry Miller"
구조화 된 정보 목록을 반환 할 때 객체 배열을 사용합니다.
$person[0] -> name = "John" -> surname = "Miller" -> address = "123 Fake St" $person[1] -> name = "Peter" -> surname = "Miller" -> address = "345 High St"
객체는 데이터 목록을 저장하는 데 적합하지 않습니다. 객체를 처리하려면 항상 키가 필요하기 때문입니다. 배열은 임의의 목록과 데이터 구조를 보유하는 두 기능을 모두 수행 할 수 있습니다.
따라서 원하는 경우 첫 번째 및 세 번째 예제에서 객체에 대한 연관 배열을 사용할 수 있습니다. 그것은 스타일과 선호도의 문제 일 뿐이라고 말하고 싶습니다.
@Deceze는 객체를 언제 사용할 지에 대해 여러 가지 좋은 점을 제시합니다 (유효성 검사, 유형 검사 및 향후 방법).
stdClass
배열과 동일한 기능을 수행하는 데 사용 하는 것은 IMHO별로 유용하지 않으며 실제 이점없이 객체의 오버 헤드를 추가 할뿐입니다. 또한 많은 유용한 배열 함수를 놓치고 있습니다 (예 :) array_intersect
. 유형 검사를 활성화하려면 최소한 고유 한 클래스를 만들거나 객체를 사용할 가치가 있도록 객체에 메서드를 추가해야합니다.
유일한 의도가 함수 호출에서 여러 임의 데이터 유형을 반환 하는 것이라면 배열에 대해 stdClass를 사용하는 것이 합당한 이점이 있다고 생각하지 않습니다 .
기술적으로 기본적으로 여러 값을 반환 할 수 없기 때문에 PHP에서 사용할 수있는 다른 모든 데이터 유형을 보유 할 수있는 컨테이너를 사용해야합니다. 그것은 객체 또는 배열입니다.
function fn1() { return array(1,2); }
function fn2() { return array('one' => 1, 'two' => 2); }
function fn3() { return (object) array(1,2); }
function fn4() { return (object) array('one' => 1, 'two' => 2); }
위의 모든 것이 작동합니다. 배열은 무시할 수있는 작은 부분으로 빠르고 입력 작업이 적습니다. 그것은 또한 일반 stdClass와는 대조적으로 명확하게 정의 된 목적을 가지고 있습니다. 둘 다 암시 적 인터페이스 만 있으므로 문서 또는 함수 본문을 살펴보고 포함 할 내용을 알아야합니다.
어떤 비용 으로든 객체를 사용하려면 ArrayObject 또는 SplFixedArray를 사용할 수 있지만 API를 살펴보면 임의의 여러 값을 반환하는 간단한 작업을 위해 해당 기능이 필요하다고 말할 수 있습니까? 나는 그렇게 생각하지 않는다. 그래도 오해하지 마십시오. stdClass를 사용하려면 사용하십시오. 그것은 아무것도 깨뜨리는 것과 같지 않습니다. 그러나 당신은 또한 아무것도 얻지 못할 것입니다. 최소한의 이점을 추가하려면이를 위해 ReturnValues라는 별도의 클래스를 만들 수 있습니다.
간단한 태깅 클래스가 될 수 있습니다.
class ReturnValues {}
또는 더 기능적인 것
class ReturnValues implements Countable
{
protected $values;
public function __construct() { $this->values = func_get_args(); }
public function __get($key) return $this->values[$key]; }
public function count() { return count($this->values); }
}
Granted, it doesn't do much and getting the values out of it is still done through an implict interface, but at least the class has a more clearly defined responsibility now. You could extend from this class to create ReturnValue objects for particular operations and give those an explicit interface:
class FooReturnValues extends ReturnValues
{
public function getFoo() { return $this->values['foo']; }
public function getBar() { return $this->values['foo']; }
}
Now the developer just has to look at the API to know which multiple values foo() will return. Of course, having to write concrete ReturnValue classes for each and every operation that might return multiple values could become tedious quickly. And personally, I find this overengineered for the initial purpose.
Anyway, hope that makes any sense.
Well, there are 3 differences:
- they have an identity. which is why the default for passing array arguments is call by value and for objects call by sharing.
- there is a semantical difference. If you use an object, anyone who reads the code understand, that the value represents the model some sort of entitity, while an array is supposed to act as a collection or a map
- And last but not least, refactoring becomes signifficantly easier. If you want to use a concrete class rather than stdClass, all you have to do is to instantiate another class. Which also allows you to add methods.
greetz
back2dos
The only OBJECTIVE vote of confidence I can find is:
json_decode
uses stdClass by default so us mortals in userland should use stdClass for similar situations.
I find stdClass objects over arrays useful when I need to keep my code clean and somewhat sentence-like readable. Take for example function getProperties()
which returns a set of properties, say data about a person (name, age, sex). If getProperties()
would return an associative array, when you want to use one of the returned properties, you would write two instructions:
$data = getProperties();
echo $data['name'];
On the other hand, if getProperties()
returns a stdClass then you could write that in just one instruction:
echo getProperties()->name;
In tests of array vs stdclass they way php handles dynamic properties is slower then associative arrays. I'm not saying this to argue micro optimization but rather if your going to do this your better off defining a dataclass with no methods and set public properties. Esp if you are using php 5.4+. Under the hood defined properties are mapped directly to a c array with no hashtable where as dynamic ones need to use a hash table.
This has the added bonus of later becoming a full class without any major interface reworking.
'Programing' 카테고리의 다른 글
Clojure의 Let 대 바인딩 (0) | 2020.11.08 |
---|---|
인터프리터 / 컴파일러는 어떻게 작동합니까? (0) | 2020.11.08 |
Xcode : 헤더 복사 : 공개 vs. 비공개 vs. 프로젝트? (0) | 2020.11.08 |
플렉스 아이템이 텍스트로 인해 넘치지 않게하는 방법은 무엇입니까? (0) | 2020.11.08 |
이미지를 BufferedImage로 변환하는 Java (0) | 2020.11.08 |