자바 디자인 모델-원형 모델 상세 설명
질문:
현재 양 한 마리(속성 포함:이름 Dolly,나이 2)가 있 습 니 다.속성 이 똑 같은 양 10 마 리 를 복제 해 야 합 니 다.
일반 해법:
구조 기,getter(),toString()을 포함 하여 Sheep 류 를 정의 합 니 다.
public class Sheep {
private String name;
private int age;
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
클 라 이언 트 에서 도 리 를 예화 한 다음 에 도리 의 속성 에 따라 10 마리 의 양 을 예화 한다.
public class Client {
public static void main(String[] args) {
Sheep sheepDolly=new Sheep("Dolly",2);
Sheep sheep1 = new Sheep(sheepDolly.getName(), sheepDolly.getAge());
Sheep sheep2 = new Sheep(sheepDolly.getName(), sheepDolly.getAge());
Sheep sheep3 = new Sheep(sheepDolly.getName(), sheepDolly.getAge());
//....
System.out.println(sheep1+",hashCode:"+sheep1.hashCode());
System.out.println(sheep2+",hashCode:"+sheep2.hashCode());
System.out.println(sheep3+",hashCode:"+sheep3.hashCode());
//...
}
}
실행 결과장단 점:
이런 방법 은 우리 가 먼저 쉽게 생각 할 수 있 는 것 이자 절대 다수의 첫 번 째 방법 이다.
그러나 단점 도 뚜렷 하 다.새로운 대상 을 만 들 때마다 원시 대상 의 속성 을 얻어 야 하고 대상 이 복잡 할 때 효율 이 낮다.또한 대상 이 실 행 될 때의 상 태 를 동적 으로 얻 을 수 없 으 며,클래스 증감 속성 은 코드 를 변경 해 야 합 니 다.
다음은 원형 모델 의 해법 을 살 펴 보 자.
원형 모드
프로 토 타 입 모드(Prototype Pattern)는 생 성 형 디자인 모델 로 한 대상 이 다른 맞 춤 형 대상 을 만 들 수 있 도록 합 니 다.어떻게 만 드 는 지 알 필요 가 없습니다.즉,프로 토 타 입 인 스 턴 스 로 생 성 대상 의 종 류 를 지정 하고 이 프로 토 타 입 을 복사 하여 새로운 대상 을 만 드 는 것 입 니 다.
작업 원리:프로 토 타 입 대상 을 만 들 대상 에 게 전달 합 니 다.만 들 대상 은 프로 토 타 입 대상 에 게 복사 요청 을 통 해 직접 만 듭 니 다.기본 Object 의 clone()방법 이나 직렬 화 를 사용 하 는 것 이다.
UML 도표:
얕 은 복사
기 존 Sheep 류 를 바탕 으로 Cloneable 인 터 페 이 스 를 실현 하고 clone 방법 을 다시 씁 니 다.
public class Sheep implements Cloneable{
private String name;
private int age;
@Override
protected Object clone() {// , clone
Sheep sheep = null;
try {
sheep = (Sheep)super.clone();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return sheep;
}
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
클 라 이언 트 호출
public class Client {
public static void main(String[] args) {
Sheep sheepDolly=new Sheep("Dolly",2);
Sheep sheep1 = (Sheep)sheepDolly.clone();
Sheep sheep2 = (Sheep)sheepDolly.clone();
Sheep sheep3 = (Sheep)sheepDolly.clone();
//....
System.out.println("sheep1:"+sheep1+",hashCode:" + sheep1.hashCode());
System.out.println("sheep2:"+sheep2+",hashCode:" + sheep2.hashCode());
System.out.println("sheep3:"+sheep3+",hashCode:" + sheep3.hashCode());
//...
}
}
실행 결과이로써 원형 모델 의 얕 은 복사 도 세 대상 을 복제 하 는 데 성 공 했 지만 진 도 를 보면 쉽 지 않다.
현재 새끼 양 에 게 친구 송아지 가 생 겼 습 니 다.Sheep 류 는 인용 속성 Cow 를 추 가 했 습 니 다.우 리 는 똑 같이 다시 복제 합 니 다.
Sheep 류
public class Sheep implements Cloneable{
private String name;
private int age;
public Cow friend;// Cow ,
@Override
protected Object clone() {
Sheep sheep = null;
try {
sheep = (Sheep)super.clone();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return sheep;
}
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
새로 추 가 된 Cow 클래스
public class Cow {
private String name;
private int age;
public Cow(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Cow{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
클 라 이언 트 호출 클론
public class Client {
public static void main(String[] args) {
Sheep sheepDolly=new Sheep("Dolly",2);
sheepDolly.friend=new Cow("Tom",1); //
Sheep sheep1 = (Sheep)sheepDolly.clone();
Sheep sheep2 = (Sheep)sheepDolly.clone();
Sheep sheep3 = (Sheep)sheepDolly.clone();
//....
System.out.println("sheep1:"+sheep1+",hashCode:" + sheep1.hashCode());
System.out.println("sheep1.friend:"+sheep1.friend+",hashCode:" + sheep1.friend.hashCode()+'
');
System.out.println("sheep2:"+sheep2+",hashCode:" + sheep2.hashCode());
System.out.println("sheep2.friend:"+sheep2.friend+",hashCode:" + sheep2.friend.hashCode()+'
');
System.out.println("sheep3:"+sheep3+",hashCode:" + sheep3.hashCode());
System.out.println("sheep3.friend:"+sheep3.friend+",hashCode:" + sheep3.friend.hashCode()+'
');
//...
}
}
실행 결과실행 결 과 를 통 해 알 수 있 듯 이 얕 은 복사 본 은 Object 의 clone()을 통 해 세 개의 새로운 대상 을 성공 적 으로 복제 하 였 으 나,복제 실례 화 대상 중의 인용 속성,즉 복제 친구 대상(세트 금지)이 없 었 다.세 개의 새로운 복제 대상 의 friend 는 원래 복제 전의 friend,즉 같은 대상 을 가리킨다.
이렇게 되면 그들 네 명의 friend 는 같은 것 을 인용 합 니 다.만약 에 한 대상 이 friend 속성 을 수정 하면 다른 세 대상 의 이 구성원 변수 값 에 영향 을 줄 것 입 니 다.
소결:
방법 1:
영리 한 사람 은 다시 한 번 cow 를 복제 하면 되 지 않 겠 습 니까?하지만 수 동 으로 돌아 가 는 것 은 추천 하지 않 습 니 다.
1.Cow 클래스 도 Cloneable 인터페이스 구현
public class Cow implements Cloneable{
private String name;
private int age;
public Cow(String name, int age) {
this.name = name;
this.age = age;
}
// , clone
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone(); // , try-catch
}
@Override
public String toString() {
return "Cow{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Sheep 류 의 clone 에 cow 를 호출 하 는 clone 을 추가 합 니 다.
public class Sheep implements Cloneable{
private String name;
private int age;
public Cow friend;// Cow ,
@Override
protected Object clone() throws CloneNotSupportedException {
Object deep = null;
// ( ) String
deep = super.clone();
// , clone
Sheep sheep = (Sheep)deep;
sheep.friend = (Cow)friend.clone();
return sheep;
}
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
클 라 이언 트 호출
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep sheepDolly=new Sheep("Dolly",2);
sheepDolly.friend=new Cow("Tom",1); //
Sheep sheep1 = (Sheep)sheepDolly.clone();
Sheep sheep2 = (Sheep)sheepDolly.clone();
Sheep sheep3 = (Sheep)sheepDolly.clone();
//....
System.out.println("sheep1:"+sheep1+",hashCode:" + sheep1.hashCode());
System.out.println("sheep1.friend:"+sheep1.friend+",hashCode:" + sheep1.friend.hashCode()+'
');
System.out.println("sheep2:"+sheep2+",hashCode:" + sheep2.hashCode());
System.out.println("sheep2.friend:"+sheep2.friend+",hashCode:" + sheep2.friend.hashCode()+'
');
System.out.println("sheep3:"+sheep3+",hashCode:" + sheep3.hashCode());
System.out.println("sheep3.friend:"+sheep3.friend+",hashCode:" + sheep3.friend.hashCode()+'
');
//...
}
}
실행 결과방법 2:
대상 직렬 화 를 통 해 딥 복사 실현(추천)
1.Cow 류 는 직렬 화 인 터 페 이 스 를 실현 하고 Cloneable 인 터 페 이 스 를 실현 할 필요 가 없다.
public class Cow implements Serializable {
private String name;
private int age;
public Cow(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Cow{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2.Sheep 류 에서 직렬 화 인터페이스 구현
public class Sheep implements Serializable { //
private String name;
private int age;
public Cow friend;
public Sheep(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Sheep{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Object deepClone() { //
//
ByteArrayOutputStream bos = null;
ObjectOutputStream oos = null;
ByteArrayInputStream bis = null;
ObjectInputStream ois = null;
try {
//
bos = new ByteArrayOutputStream();
oos = new ObjectOutputStream(bos);
oos.writeObject(this); //
//
bis = new ByteArrayInputStream(bos.toByteArray());
ois = new ObjectInputStream(bis);
Sheep sheep = (Sheep) ois.readObject();
return sheep;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
//
try {
bos.close();
oos.close();
bis.close();
ois.close();
} catch (Exception e2) {
System.out.println(e2.getMessage());
}
}
}
}
3.클 라 이언 트 호출
public class Client {
public static void main(String[] args) throws CloneNotSupportedException {
Sheep sheepDolly=new Sheep("Dolly",2);
sheepDolly.friend=new Cow("Tom",1); //
Sheep sheep1 = (Sheep)sheepDolly.deepClone();
Sheep sheep2 = (Sheep)sheepDolly.deepClone();
Sheep sheep3 = (Sheep)sheepDolly.deepClone();
//....
System.out.println("sheep1:"+sheep1+",hashCode:" + sheep1.hashCode());
System.out.println("sheep1.friend:"+sheep1.friend+",hashCode:" + sheep1.friend.hashCode()+'
');
System.out.println("sheep2:"+sheep2+",hashCode:" + sheep2.hashCode());
System.out.println("sheep2.friend:"+sheep2.friend+",hashCode:" + sheep2.friend.hashCode()+'
');
System.out.println("sheep3:"+sheep3+",hashCode:" + sheep3.hashCode());
System.out.println("sheep3.friend:"+sheep3.friend+",hashCode:" + sheep3.friend.hashCode()+'
');
//...
}
}
실행 결과원형 모드 요약:
이 글 은 여기까지 입 니 다.당신 에 게 도움 을 줄 수 있 기 를 바 랍 니 다.또한 당신 이 우리 의 더 많은 내용 에 관심 을 가 져 주 실 수 있 기 를 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.