관리 메뉴

HAMA 블로그

객체 복제 in Polyglot 본문

소프트웨어 사색

객체 복제 in Polyglot

[하마] 이승현 (wowlsh93@gmail.com) 2015. 11. 13. 11:39

안녕하세요 (_._)  

테크란에 너무 어렵거나, 남에 얘기만 써있는거 같아서..기본이되며 항상 마주치는 주제를 써보려합니다.  객체복사에 관한 글입니다. 언어는 현재  만들고있는 프로젝트에 사용된 C++,JAVA, Javascript ,Python 에 추가적으로 Scala 가 될것이구요. 새로운내용은 아니라 , 복습차원에서 글을 쓰고 자료를 찾아 보았습니다.


* 복제/복사 뚜렷한 구분을 하지 않고  혼용하였습니다.  =  , clone ,  copy , duplicate 의 차이는 개발자 맘이고

중요하게 구분해야할것은  깊은복사/얕은복사의 차이점입니다. 


이런저런 이야기 

작년에 JAVA 로 개발을 시작하고 "Effective Java"  라는 책을 읽으면서 , Item 11 항목을  참 어렵게 읽었던 기억이 있습니다. "clone 오버라이드는 신중히 하자"  뭐 이런거였는데요."사족"  즉 뱀의 다리 잖습니까?   쓸데 없이 엄청 주저리주저리 하시는구만 ..하는 생각이 들었습니다.C++ 로 그 동안 객체복사할때는 그냥 그걸 구현하면 된 것들을 JAVA 에서는 희안하게 구속해 놓았구나..(Object 에 이미 존재하다보니, 좀 신경쓰인다고나 할까? 흰 도화지에 그림을 그리고 싶은데 , 이미 테두리가 그려져있는 그림에 색칠만 칠하는 느낌? ) 뭐 안전장치라고도 볼수있고,편의성 제공이라고도 볼수있고,  길잡이라고도 볼수있겠지요. 좀 과한 길잡이 같지만 ㅎㅎ 여기서 잠깐 길에서 벗어나보면 "인터페이스" 도 그렇다고 볼수있겠습니다.  자바에서는 굳이 "인터페이스" 라는 개념을 실제 문법으로 추가하므로써 좀 더 객체지향이라는 목적지에 잘 도착하도록 안내한다고 볼수있습니다. ( 다중상속을 위해 만든것이다? 아닙니다)  


다시 객체복사 경험담으로  돌아와서 ,제가 C++ 로 개발할때는 clone 더미에서 살았습니다. 
굉장히 많은 부분 clone 이 객체에 관여되있고, 신경써왔는데 자바로 개발하면서부터 별로 객체복사에 대해서 신경쓸 일이 많지 않더군요.물론 언어때문이 아닙니다. 만들었던 솔루션의 목적이 다르기 때문인데요. 과거 C++ 로 작업할땐 무엇 때문이었냐 하면  편집기를 만들었었기 때문입니다.


객체복사(Deep)를 하는 이유는 단순히 ,  " 깨끗한 놈은 그냥 놔두고 ,  더럽히고 싶은 닮은 놈을 만들자 "  입니다. "깨끗한 놈을 , 더럽히지 말고 같이 쓰자" 라면 굳이 객체복사를 할 필요는 없습니다. (객체를 가르키는 참조만 복사하면됨) 그럼 깨끗한놈은 놔두고, 더럽히고 싶은놈을 만들고 싶은 경우를 편집기에서 생각해보면,


                         

                                                                       (그림 - 1)


그림 - 1 은 편집기에서 어떤 속성을 탭 형식으로 보여주고 있습니다. 
저 탭이 하나의 객체라고 치면 (가 : 1.34 , 나 : "okky")  같이 깨끗한 객체를 일단 모셔두고,  그 객체를 복사해서  값을 마구 바꿔보다가 (값을 바꾸는건 사용자겠지요) 바꾸기로 마음먹으면 "저장" 을 눌러서  "복사한 객체" 의 내용을 원본에 덮어쓰고 파일 혹은 DB 에 save 하고,  그냥 안바꾸기로 마음먹었으면 "취소" 를 눌러서 그  "복사한 객체" 를 delete 시켜버리면 깔끔해집니다.Undo, Redo 를 위한 Command 패턴에서도 기억되기위한 객체로 복사해놓을수 있구요. 


객체 복제의 모습들 


객체 복제는 크게 3가지 방식으로 이루어집니다.


                                                                (그림 - 1  레퍼런스 복사)

                                                  

  -   a 레퍼런스는 A 객체를 가르킵니다. 

  -   a 레퍼런스를 복사해서 a-2 레퍼런스를 만듭니다.

  -   a-2 레퍼런스가 A 객체를 더럽히면 a 레퍼런스도 더렵혀진 A 객체를 사용하게됩니다. 

  -   즉 더럽히지 않을꺼란 보장이 되면 이렇게 복사해도 됩니다. 

  -   더렵혀진 값을 사용해도 된다면 이렇게 해도 됩니다.

  -   더렵혀지기 전의 깨끗한 원본이 필요없다면 이렇게 해도 됩니다.                           


                                                                (그림 - 2  앝은 복사)


  -   a 레퍼런스는 A 객체를 가르킵니다. 

  -   A 객체를 복사해서 a-2 레퍼런스를 통해 가르키게 합니다.  

  -   a 레퍼런스가 A 객체의 값 "1" 을 바꾸어도 a-2 레퍼런스에는 영향이 안미칩니다.

  -   a 레퍼런스가 A 객체 "안의" B 객체를 가르키는 레퍼런스를 통해 B 객체의 "Hi" 를 변경하면
      a-2 레퍼런스에 영향을 미칩니다.

  -   A 객체가 기본형으로만 이루어져있다면 이렇게 복제해도 됩니다. (java 에서는 int, float 이런) 

  -   A 객체 안에 다른 객체를 참조하는것이 들어있다면,  (그림 - 2  레퍼런스 복사) 와 같은 운명        
      에 처합니다.



                                                               (그림 - 3  깊은 복사)


  -   a 레퍼런스는 A 객체를 가르킵니다. 

  -   A 객체를 복제 해서 a-2 레퍼런스를 통해 가르키게 합니다.  

   -  A 객체를 복제 할때 B 객체도 같이 복제합니다.  

  -   a 레퍼런스가 A 객체의 값 "1" 을 바꾸어도 a-2 레퍼런스에는 영향이 안미칩니다.

  -   a 레퍼런스가 B 객체의 값 "Hi" 을 바꾸어도 a-2 레퍼런스에는 영향이 안미칩니다.

  -   이렇게 되면 a-2 레퍼런스가 어떤 짓을 해도 , a  레퍼런스가 가르키는 객체들은 순수함을 잃지        

       않게됩니다.

  -   다만 메모리가 더 소비되며, 객체 복제 비용이 듭니다. 


흠흠 점심시간이네요 ㅜㅜ 

아래에 정리 좀 해두고, 점진적으로 마무리 하겠습니다. 



각 언어에서의 복제도 언어별로 이디엄이 있긴하지만 , 괜히 행사코드라든지, 잡다구리한것들에 의해

그 핵심을 놓쳐서는 안됩니다. 중요한건 깊이 복사하느냐 , 앝게 복사하느냐 일 뿐입니다. 


C++ 에서의 객체 복제

이디엄 :  단순 대입  / 복사 생성자 / 대입 연산자 오버로딩 /  ShallowCopy 와 DeepCopy 함수를 만들기

http://soen.kr/lecture/ccpp/cpp3/26-2-2.htm  (복사생성자: 기초 )

http://soen.kr/lecture/ccpp/cpp3/28-3-3.htm  (대입연산자 오버로딩: 기초) 

http://accu.org/index.php/journals/522  (중급)


JAVA 에서의 객체 복제  

이디엄 :  Object.clone , super.clone() / cloneble 인터페이스 / CloneNotSupportedException

기초 : http://javacan.tistory.com/30   

clone() vs 복사생성자 vs 복사팩토리메소드 

http://stackoverflow.com/questions/1106102/clone-vs-copy-constructor-vs-factory-method

http://www.javacodegeeks.com/2014/01/which-is-better-option-cloning-or-copy-constructors.html



JavaScript  에서의 객체 복제 

이디엄: prototype ,  hasOwnProperty 

http://www.nextree.co.kr/p7323/   (프로토타입 이해) 

http://blog.soulserv.net/understanding-object-cloning-in-javascript-part-i/ (얇은복사)

http://heyjavascript.com/4-creative-ways-to-clone-objects/  (객체 복사 방법 4가지) 


Scala  에서의 객체 복제 

- 추천해주실만한 블로그나 글 있으면 댓글로 공유해주세요


Python 에서의 객체복제

http://kkoseul.tistory.com/m/post/53


Comments