Zend 엔진 2.0 설계초안 – 02.개선된 객체모델

개선된 객체모델(Revamped object model)

객체 핸들(object handle)

Zend 엔진 1.0 객체 모델에서는 생성된 객체를 값으로 취급하도록 설계되어 있습니다. 이것은 프로그래머가 변수에 값을 할당하거나 함수에 인수를 전달하는 것과 같은 조작을 할 때 정수와 문자열과 같은 다른 기본형(primitive types)을 다루는 것과 같은 방법과 매우 유사하게 객체를 다룬다는 것을 의미합니다. 이것은 모든 객체가 복사되고 있다는 것을 의미합니다.

반면에 자바에서는 값이 아닌 핸들을 가지고 객체를 참조합니다. 핸들이란 객체 ID라고 생각할 수 있지요. 제 홈페이지에서 설명하고 있는 ‘참조(레퍼런스)’ 정보에서 일부 언급하였듯이 자바에서는 객체를 변수에 할당하거나, 객체를 매개변수로 메소드에 전달하거나 메소드로부터 반환할 때, 전달되는 것은 이러한 객체의 참조(레퍼런스)이지 객체의 복사본이 아닙니다.

그러나 PHP3 또는 PHP4에서는 객체 핸들이 아닌 객체 자체를 다루도록 모델링되어 있기 때문에 객체를 다루는데 있어서 매우 비효율이며 소멸자와 같은 객체 특성을 구현하는데 많은 문제가 발생합니다. 결국 객체를 다룰 때는 자바에서와 같이 참조로 전달하는 것이 효율적이며 이와같이 객체 모델을 핸들 지향 모델(handle oriented model)로 변경하게 되면 어드레싱을 하는데 있어 소멸자, 메소드 반환값으로 역참조하기(de-referencing method return values), 객체 복사(object duplication)에 관하여 매우 엄격히 제어할 수 있는 등 객체와 관련된 많은 요구를 수용할 수 있게 됩니다.

새로 제안된 객체 모델은 자바 모델에 의해서 매우 많이 영향을 받습니다. 일반적으로, 새로운 객체를 생성할 때 객체 그 자체대신에 해당 객체의 핸들을 얻게 될 것입니다. 이 핸들을 함수에 전달하고, 할당하고 복사하였을 때 복사되고 보내지고 할당되는 것은 핸들만 입니다. 객체 자체는 결코 복사 또는 중복되지 않습니다.

이것은 한 객체의 모든 핸들이 항상 동일한 객체를 지정하도록 하기 때문에 객체를 다루는데 의미가 분명해지며 불필요한 중복과 혼란스러운 동작을 줄여줄 수 있습니다.

Zend 엔진 1.0 객체 모델

앞에서도 설명하였지만 PHP4에 탑재된 Zend 엔진 1.0 객체 모델에서는 생성된 객체를 값으로 취급하도록 설계되어 있습니다.

다음 코드가 Zend 엔진 1.0에서 어떻게 동작하는지 살펴보겠습니다.

16행에서 객체의 멤버변수 member은 문자열 “bar”을 값으로 설정됩니다. 17행에서 객체 $object가 함수 foo에 값에 의해 보내질 때(call by value) 객체는 복제(duplicate)됩니다. 그러므로 foo()를 호출하면 $object의 복제물을 가지고 12행에서 $obj->setMember(“foo”)를 호출하게 될 것입니다. 그러면 18행에 의해 출력된 결과는 “bar”가 될 것입니다.

이것이 오늘날까지 PHP3 또는 PHP4 스크립팅 엔진이 동작하던 방식입니다. 어쩌면 많은 개발자들이 아직까지도 PHP3 또는 PHP4에서 항상 동일한 객체를 다루지 않고 복제된 객체를 다룬다는 사실 조차도 눈치채지 못하였을 수도 있을 것입니다. 제 홈페이지 ‘참조(레퍼런스)’ 기사를 주의깊게 읽어본 독자라면 이 문제에 대하여 아래와 같이 복제 대신에 참조에 의한 객체 전달을 통하여 해결할 수 있다는 것을 알았겠지요.

위의 참조(레퍼런스)를 이용한 개선된 예제에서 객체 생성할 때의 발생하는 객체 복제의 비효율성까지 추가로 개선코자 한다면 15행의 ‘$object = new MyClass();’ 대신에 ‘$object = & new MyClass();’라고 코딩하였을 수도 있었겠지요.

Zend 엔진 2.0에서의 개선된 객체 모델

개선된 Zend 엔진 2.0 객체 모델에서는 이전과 같이 객체를 다루지 않아도 됩니다. 객체 모델의 커다란 변화에도 불구하고 객체의 기본적인 사용법은 참조기호 & 없이 이전 버전의 스크립트 엔진에서와 거의 동일할 것입니다. 새로운 객체 인스턴스를 생성하고 사용하기 위해서는 다음과 같이 합니다.

위의 코드에서 클래스 MyClass의 새로운 인스턴스에 대한 핸들을 $object에 할당할 것이고 새로운 인스턴스에 대한 메소드를 호출할 것입니다.

새로운 객체 모델은 코드의 직관적인 구현을 훨씬 더 많이 허용할 것입니다. 17행에서 객체 핸들(ID)이 값으로 foo()에 전달됩니다. foo() 내부에서 객체는 이 핸들에 의하여 가져오므로 setMember() 메소드는 원래의 인스턴스화된 객체를 호출하는 것이며 복사본으로 호출하는 것이 아닙니다. 그러므로 18행에 의해 “foo”가 출력될 것입니다.

이러한 접근은 객체가 생성되고 복제될 때 개발자에게 좀더 엄격하게 관리하도록 해줍니다. 이와 같이 객체 핸들을 foo()에 전달하여 객체를 다루도록 하면 불필요한 객체 복제를 줄여줄 것이고 이에따라 실행시간 성능을 부가적으로 개선시킬 것입니다.

답글 남기기