프로토타입 패턴
프로토타입 패턴이란
- 기존에 존재하던 인스턴스를 복제하여 새로운 인스턴스를 만드는 방법을 제공하는 패턴
- 만약 어떤 인스턴스를 만드는데 디비를 탄다거나, 네트워크를 타는 등 비용이 많이 든다면
- 그 인스턴스를 그대로 복제해서 사용함으로써 비용을 절약할 수 있을 것이다.
- 보통 clone() 메서드를 사용하여 프로토타입 패턴을 구현한다.
간단한 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person implements Cloneable {
private Dog dog;
private String name;
private int age;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// constructor()
// equals()
}
- 사람을 나타내는 Person 클래스와
- 사람이 키우는 강아지인 Dog 클래스가 있다.
- Person은 Object의 clone()을 오버라이딩 하고 있다.
- 이 메서드를 사용하기 위해선 Cloneable을 구현해야 한다.
1
2
3
4
5
6
7
8
9
Dog dog = new Dog("또롱이", 23);
Person person = new Person(dog, "김철수", 30);
Person clone = (Person) person.clone();
System.out.println(person == clone); // false
System.out.println(person.equals(clone)); // true
- 먼저 만들었던 person 객체와 person을 복제해 만든 clone 객체를 볼 수 있다.
- person과 clone은 같은 인스턴스냐고 물었을 땐 false이지만,
- 동등한 인스턴스냐고 물었을 땐 true이다.
얕은 복사
- Object가 제공하는 clone()은 기본적으로 shallow copy이다.
- 이는 얕은 복사란 뜻으로, 객체가 참고하고 있는 다른 인스턴스까지는 카피하지 않는 것이다.
- 예를 들면, Person의 데이터를 전부 카피하지만 Person이 참조하는 Dog는 참조를 그대로 가져간다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person {
private Dog dog;
private String name;
private int age;
public Object clone() { // 얕은 복사
return new Person(dog, name, age);
}
// constructor()
// equals()
// getters()
}
- 위의 Person의 clone()은 얕은 복사로 구현한 코드이다.
- 얕은 복사이기 때문에 dog 인스턴스를 그대로 가져간 걸 알 수 있다.
1
2
3
4
5
6
7
8
Dog dog = new Dog("또롱이", 23);
Person person = new Person(dog, "김철수", 30);
Person clone = (Person) person.clone();
System.out.println(person.getDog() == clone.getDog()); // true
- person도 clone도 같은 인스턴스인 또롱이의 주인이 되었다.
깊은 복사
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person {
private Dog dog;
private String name;
private int age;
public Object clone() { // 깊은 복사
Dog newDog = new Dog(dog.getName(), dog.getAge());
return new Person(newDog, name, age);
}
// constructor()
// equals()
// getters()
}
- 이번엔 clone()을 깊은 복사로 구현하였다.
- 또롱이마저 복사하여 서로 다른 강아지 인스턴스를 참조하게 된다.
1
2
3
4
5
6
7
8
9
Dog dog = new Dog("또롱이", 23);
Person person = new Person(dog, "김철수", 30);
Person clone = (Person) person.clone();
System.out.println(person.getDog() == clone.getDog()); // false
System.out.println(person.getDog().equals(clone.getDog())); // true
- 이번엔 아주 깊은 곳까지 복제를 해서 또롱이마저 복제했다.
- person과 clone이 참조하는 dog 객체는 동등하나 같진 않다.
This post is licensed under CC BY 4.0 by the author.