phpclass/객체모델2002. 12. 21. 15:15
객체 복제(Object Cloning)
Zend 1.0 객체 모델에서는 객체를 다룰 때 기본적으로 값으로 다루도록 설계되었기 때문에 객체를 함수의 인자로 전달하거나 함수로부터 객체가 반환될 때 또 할당문을 이용하여 객체가 할당될 때 기본적으로 객체 복사가 됩니다. 복사하는 동안에 Zend 엔진 1.0은 객체 프로퍼티의 전부에 대한 동일한 복사본을 만들기 위하여 비트 단위 복사(bitwise copy)를 하였습니다.
그러나 이러한 복사를 기반으로 한 객체모델에서는 자원 이용의 비효율성과 실행 시간의 지연과 같은 문제를 근원적으로 떠안고 있을 수밖에 없었으며 객체지향 프로그래밍의 여러 특징을 구현하는데 한계를 가지게 되었습니다. 사실 대부분의 경우에서 개발자들은 완전히 복제된 프로퍼티를 가진 객체의 복사를 생성할 필요는 없었습니다.
Zend 2.0에서의 객체 복제
객체 참조
Zend 2.0 객체 모델에서는 객체를 다룰 때 값이 아닌 참조로 다루도록 개선되었습니다. 이러한 이유로 원본 객체로부터 할당된 객체 또는 함수에 의해 반환된 객체를 다루게 되면 원본 객체 그 자체를 다루게 되지요.
객체 복사
그런데 때로는 원본 객체를 원래 상태로 유지하여야 할 경우도 있을 것입니다. 이러한 경우에는 예전 Zend 엔진 1.0에서처럼 참조가 아닌 복사를 하여 복사된 객체를 가지고 작업을 하여야 합니다. Zend 엔진 1.0에서야 기본적으로 객체 참조가 아닌 객체 복사였기 때문에 전혀 문제가 되지 않았었지만 Zend 엔진 2.0에서는 기본적인 처리가 객체 참조가 되기 때문에 객체 복사를 위한 새로운 수단이 필요하게 되었지요.
Zend 엔진 2.0에서 객체 복사를 위한 수단이 바로 __clone() 메소드입니다. __clone 메소드를 호출함으로써 원본 객체를 복제한 새로운 객체가 생성되는 것이지요.
[code php;gutter:false] <?php
$copy_of_object = $object->__clone();
?> [/code]
객체 복사를 하기 위해서는 반드시 __clone() 메소드를 이용해야 합니다. __clone() 메소드를 이용하면 원본 객체를 복사한 동일한 객체를 만들 수 있으며 이 객체의 멤버를 수정하더라도 원본 객체는 원래 상태를 그대로 유지할 수가 있습니다.
__clone() 메소드의 사용자 정의
새로운 객체의 복사본을 생성하기 위하여 __clone() 메소드를 호출하게 되면 Zend 엔진 2.0은 클래스 내에 정의된 __clone() 메소드가 존재하는지 확인할 것입니다.
만약 정의된 __clone() 메소드가 없다면 Zend 엔진 2.0에 내장된 __clone() 메소드를 호출하게 되고 이 메소드에 의해 객체 프로퍼티 전체를 복사할 것입니다.
만약 정의된 __clone() 메소드가 있다면 생성된 객체에서 필요로하는 프로퍼티에 대하여는 정의된 __clone() 메소드 내에서 직접 설정해 주어야 합니다.
[code php;gutter:false] <?php
class MyCloneable {
static $id = 0;

function MyCloneable() {
$this->id = self::$id++;
}

function __clone() {
$this->name = $clone->name;
$this->address = 'New York';
$this->id = self::$id++;
}
}

$obj = new MyCloneable();

$obj->name = 'Hello';
$obj->address = 'Tel-Aviv';

print $obj->id . "\n";

$obj = $obj->__clone();

print $obj->id . "\n";
print $obj->name . "\n";
print $obj->address . "\n";
?> [/code]
자식클래스는 부모클래스의 __clone() 메소드를 오버라이드(override) 할 수 있습니다만, 그 경우 자식클래스에서 부모클래스의 __clone() 메소드를 호출하려면 아래와 같이 'parent' 키워드를 이용하여 참조합니다.
[code php;gutter:false] <?php
class SubCloneable extends SuperCloneable {
static $id = 0;

function SubCloneable() {
$this->id = self::$id++;
}

function __clone() {
$this = parent::__clone();
$this->name = $clone->name;
$this->address = 'New York';
$this->id = self::$id++;
}
}
?> [/code]

Posted by 방글24