effective-swift

Item 13. clone 재정의는 주의해서 진행하라

Item 13에서는 clone 메서드를 재정의할 때 주의할 점들을 설명합니다.

Object.clone()

자바 Object 클래스에서 기본으로 구현되어 있는 clone() 메소드는 Cloneable 인터페이스를 구현했는지 확인하고, 구현하지 않았다면 예외를 던집니다. 구현되어 있으면, 원본과 같은 객체를 새로 생성 후 모든 필드들에 원본 필드를 각각 대입시켜 복사하는 방식으로 구현되어 있습니다.

clone 메서드의 일반 규약

clone 메서드의 일반 규약을 요약하면, clone 메서드는 원본 객체와 같은 타입의 복사본을 생성해 반환하며, 관례상 반환된 객체와 원본 객체는 독립적이라는 것입니다. 하지만 이 규약들이 필수로 지켜져야 하는 것은 아닙니다.

가변 상태를 참조하지 않는 클래스의 clone

모든 필드가 primitive 타입이거나, immutable한 객체를 참조하는 변수들이라면 상위 클래스의 clone()을 호출하기만 하면 됩니다.

가변 상태를 참조하는 클래스의 clone

가변 객체를 참조하는 클래스의 경우, 복사본에서의 변경으로 인해 원본 객체까지 변경되면 안되므로 해당 객체가 참조하고 있는 (가변)객체들까지 복사본을 생성하여야 합니다.

결론

Cloneable을 구현해야 하는 경우가 아니라면 복사 생성자와 복사 팩터리를 제공하는 편이 더 낫습니다.

public Yum(Yum yum) { ... }; // 복사 생성자
public static Yum newInstance(Yum yum) { ... }; // 복사 팩터리

스위프트에서는…

struct의 경우 value type 이므로 객체를 다른 변수에 대입하면 복사본이 만들어집니다. class의 경우, 객체를 복사하는 기능을 지원하려면 생성자 혹은 정적 팩터리 메서드를 구현하는 편이 좋습니다.