C\#디자인 모델 시리즈 튜 토리 얼-원형 모델

1.개술
존재 하 는 인 스 턴 스 를 복사 해서 새로운 인 스 턴 스 를 만 듭 니 다.복 사 된 인 스 턴 스 를 원형 이 라 고 하 는데 이 원형 은 맞 춤 형 입 니 다.
2.모드 속 캐릭터
2.1 추상 원형 류(Abstract Prototype):복제 인터페이스 제공
2.2 구체 적 인 원형 류(Concrete Prototype):그리고 복제 인터페이스의 구체 적 인 원형 류 를 실현 했다.
3.사례:구직 사이트 에 서 는 현재 여러 개의 이력 서 를 지원 하고 있 습 니 다.이력 서 를 작성 할 때마다 처음부터 끝까지 작성 해 야 한다 면 그것 도 매우 우울 한 일 입 니 다.사실 우리 의 구직 직무 에 따라 서로 다른 이력 서 는 부분 적 인 내용 만 수정 하면 되 고 모두 새로운 이력 서 를 다시 만 들 지 않 아 도 될 것 입 니 다.이력 서 를 복사 한 후에 부분 수정 을 하 는 것 이 가장 안심 입 니 다!
3.1 실현 도표
//img.jbzj.com/file_images/article/201606/201606020932062.png
아 날로 그 해독
.NET 에서 System 네 임 스페이스 는 우리 에 게 ICloneable 인 터 페 이 스 를 제공 했다.이것 은 하나의 방법 인 Clone()을 포함 하고 이 인 터 페 이 스 를 실현 하면 원형 모델 을 완성 했다.
3.2 현대 코드 를 사실 화하 기 전에 심 한 복제 와 얕 은 복 제 를 이해 해 야 한다.
3.2.1 얕 은 복사:원래 대상 의 모든 필드 를 하나씩 새로운 대상 으로 복사 합 니 다.필드 가 값 형식 이 라면 복사 본 을 새로운 대상 으로 간단하게 복사 하고 새로운 대상 의 값 형식 필드 를 바 꾸 면 원래 대상 에 영향 을 주지 않 습 니 다.필드 가 인용 형식 이 라면 인용 을 복사 합 니 다.대상 에서 인용 형식 필드 의 값 을 바 꾸 면 원래 대상 에 영향 을 줄 수 있 습 니 다.예 를 들 어 한 대상 이 인용 유형(예 를 들 어 업무 경력)을 가리 키 는 필드 가 있 고 우리 가 이 대상 에 대해 얕 은 복 제 를 했다 면 두 대상 은 같은 인용(즉 같은 업무 경력)을 인용 할 것 이다.
3.2.2 딥 복사:얕 은 복사 와 다른 점 은 인용 유형 에 대한 처리 입 니 다.새로운 대상 에서 인용 유형 필드 를 복사 한 새로운 대상 에 게 가리 키 고 새로운 대상 에서 인용 한 모든 대상 을 바 꾸 면 원래 의 대상 에서 대응 하 는 필드 의 내용 에 영향 을 주지 않 습 니 다.예 를 들 어 한 대상 이 인용 형식(예 를 들 어 업무 경력)을 가리 키 는 필드 가 있 고 이 대상 에 대해 깊 은 복 제 를 했다 면 제 문 은 새로운 대상(즉,새로운 업무 경력)을 만 들 것 입 니 다.
3.3 이력서 의 간단 한 복사 실현

 /// <summary>
 ///    ICloneable      
 /// </summary>
 public class Resume:ICloneable
 {
 public Resume()
 {
  mWorkExperience = new WorkExperience();
 }

 private string mName;
 private string mSex;
 private int mAge;
 private WorkExperience mWorkExperience;

 public string Name
 {
  get { return mName; }
  set { mName = value; }
 }

 public string Sex
 {
  get { return mSex; }
  set { mSex = value; }
 }

 public int Age
 {
  get { return mAge; }
  set { mAge = value; }
 }

 /// <summary>
 ///          
 /// </summary>
 public WorkExperience WorkExperience 
 { 
  get { return mWorkExperience; } 
 }

 public void SetWorkExperience(DateTime startDate, DateTime endDate, string company, string position)
 {
  this.mWorkExperience.Company = company;
  this.mWorkExperience.EndDate = endDate;
  this.mWorkExperience.StartDate = startDate;
  this.mWorkExperience.Position = position;
 }

 /// <summary>
 ///   ICloneable   Clone  
 /// </summary>
 /// <returns></returns>
 public object Clone()
 {
  // .Net               
  return this.MemberwiseClone();
 }
 }

 /// <summary>
 ///      
 /// </summary>
 public class WorkExperience
 {
 public DateTime StartDate { get; set; }
 public DateTime EndDate { get; set; }
 public string Company { get; set; }
 public string Position { get; set; }
 }

다음은 테스트 코드 입 니 다.

 [TestMethod]
 public void TestShallowCopy()
 {
  Resume myFirstResume = new Resume
  {
  Age = 29,
  Name = "Kevin Wang",
  Sex = " ",
  };
  myFirstResume.SetWorkExperience(new DateTime(2006, 7, 1), new DateTime(2007, 7, 1), "My First Company", "Software Engineer");

  Resume mySecondResume = (Resume)myFirstResume.Clone();
  mySecondResume.SetWorkExperience(new DateTime(2007, 8, 1), new DateTime(2008, 8, 1), "My Second Company", "Software Engineer");

  Resume myThirdResume = (Resume)myFirstResume.Clone();
  myThirdResume.SetWorkExperience(new DateTime(2008, 8, 1), new DateTime(2009, 8, 1), "My Third Company", "Senior Software Engineer");

  Assert.AreEqual("My First Company", myFirstResume.WorkExperience.Company);
  Assert.AreEqual("My Second Company", mySecondResume.WorkExperience.Company);
  Assert.AreEqual("My Third Company", myThirdResume.WorkExperience.Company); 
 }

여기 서 기대 하 는 것 은 세 가지 단언 이 모두 성공 적 으로 실 행 될 수 있 지만 실패 한 것 이다.그 이 유 는 얕 은 복 제 를 사 용 했 기 때문에 my First Resume,my SecondResume 과 my Third Resume 은 같은 대상 을 인 용 했 기 때문에 최종 결 과 는 세 개의 이력서 의 WorkExperience.Company 가 모두'My Third Company'이기 때문이다.
3.4 이력서 의 깊 은 복사 실현

 /// <summary>
 ///    ICloneable      
 /// </summary>
 public class Resume : ICloneable
 {
 public Resume()
 {
  mWorkExperience = new WorkExperience();
 }

 /// <summary>
 ///                             
 /// </summary>
 /// <param name="workExperience"></param>
 private Resume(WorkExperience workExperience)
 {
  this.mWorkExperience = (WorkExperience)workExperience.Clone();
 }

 private string mName;
 private string mSex;
 private int mAge;
 private WorkExperience mWorkExperience;

 public string Name
 {
  get { return mName; }
  set { mName = value; }
 }

 public string Sex
 {
  get { return mSex; }
  set { mSex = value; }
 }

 public int Age
 {
  get { return mAge; }
  set { mAge = value; }
 }

 public WorkExperience WorkExperience
 {
  get { return mWorkExperience; }
 }

 /// <summary>
 ///       
 /// </summary>
 /// <param name="startDate"></param>
 /// <param name="endDate"></param>
 /// <param name="company"></param>
 /// <param name="position"></param>
 public void SetWorkExperience(DateTime startDate, DateTime endDate, string company, string position)
 {
  this.mWorkExperience.Company = company;
  this.mWorkExperience.EndDate = endDate;
  this.mWorkExperience.StartDate = startDate;
  this.mWorkExperience.Position = position;
 }

 /// <summary>
 ///   ICloneable   Clone  
 /// </summary>
 /// <returns></returns>
 public object Clone()
 {
  //       MemberwiseClone       ,             。          ,          
  Resume newResume = new Resume(this.mWorkExperience);
  newResume.mSex = this.mSex;
  newResume.mName = this.mName;
  newResume.mAge = this.mAge;

  return newResume;
 }
 }

 public class WorkExperience :ICloneable
 {
 public DateTime StartDate { get; set; }
 public DateTime EndDate { get; set; }
 public string Company { get; set; }
 public string Position { get; set; }

 public object Clone()
 {
  //   .Net               ,             (string       , .NET         ,           )。
  return this.MemberwiseClone();
 }
 }

테스트 코드 는 다음 과 같 습 니 다.

 [TestMethod]
 public void TestDeepCopy()
 {
  Resume myFirstResume = new Resume
  {
  Age = 29,
  Name = "Kevin Wang",
  Sex = " ",
  };
  myFirstResume.SetWorkExperience(new DateTime(2006, 7, 1), new DateTime(2007, 7, 1), "My First Company", "Software Engineer");

  Resume mySecondResume = (Resume)myFirstResume.Clone();
  mySecondResume.SetWorkExperience(new DateTime(2007, 8, 1), new DateTime(2008, 8, 1), "My Second Company", "Software Engineer");

  Resume myThirdResume = (Resume)myFirstResume.Clone();
  myThirdResume.SetWorkExperience(new DateTime(2008, 8, 1), new DateTime(2009, 8, 1), "My Third Company", "Senior Software Engineer");

  Assert.AreEqual("My First Company", myFirstResume.WorkExperience.Company);
  Assert.AreEqual("My Second Company", mySecondResume.WorkExperience.Company);
  Assert.AreEqual("My Third Company", myThirdResume.WorkExperience.Company); 
 }

테스트 를 실행 하고 테스트 를 통과 하 는 것 이 바로 우리 가 기대 하 는 결과 이다.
4.모델 총화
4.1 장점
4.1.1 대상 의 생 성 디 테 일 을 숨 기 고 많은 자원 을 사용 해 야 하 는 초기 화 클래스 에 있어 성능 도 크게 향상 되 었 습 니 다.
4.1.2 새로운 대상 이 필요 할 때 Clone 을 사용 하여 new 로 구축 하지 않 고 빠르게 만 들 수 있 습 니 다.
4.2 단점
4.2.1 모든 유형 은 하나의 Clone 방법 이 필요 하고 전면적으로 고려 해 야 한다.깊 은 복사 에 있어 서 모든 관련 유형 은 IClonable 인 터 페 이 스 를 실현 하지 못 하고 한 필드 를 추가 하거나 수정 할 때마다 Clone 방법 을 업데이트 해 야 합 니 다.
4.3 적용 필드
4.3.1 류 초기 화 는 매우 많은 자원 을 소화 해 야 하 는데 이 자원 은 데이터,하드웨어 자원 등 을 포함한다.
4.3.2 new 를 통 해 대상 을 만 들 려 면 매우 번 거 로 운 데이터 준비 나 접근 권한 이 필요 하 며 원형 모드 를 사용 할 수 있 습 니 다.
4.3.3 한 대상 이 다른 대상 에 게 접근 할 수 있 도록 제공 해 야 하고 각 호출 자가 그 값 을 수정 해 야 할 때 원형 모드 로 여러 대상 을 복사 하여 호출 자 에 게 사용 하도록 고려 할 수 있다.
이상 이 바로 본문의 전체 내용 입 니 다.여러분 께 참고 가 될 수 있 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기