안녕하세요 삽잡이입니다.
객체의 직렬화를 살펴보도록 하겠습니다.
객체의 직렬화는 '객체'를 바이트 배열로 써놨다가,
다시 바이트 배열로 복원하려고 쓰는 기능입니다.
이제부터 본격적으로 stream에 대한 이야기를 하려고 하는 것입니다.
파일, 스트림을 만든 이유는 객체에 무엇인가를 쓰기 위해서입니다.
즉, 어플리케이션의 무엇인가를 쓰기 위해서라는 것이죠.
그런데, 이전 시간에 공부한 내용은 객체를 사용한 것이 아닙니다.
객체 지향에서 과연 얼만큼
문자열만을... 혹은 정수만을 읽고 쓰겠습니까?
객체가 주가 되는 일이 다반사지 않겠습니까?
프로그램은 사용자와 소통하는 UI영역과
이 UI의 데이터를 보관하고 보여주기 위한 데이터 모델로 나뉠 수 있습니다.
데이터는 다시 UI와 밀접한 View 모델이라는 것과,
관련성 없는 그냥 모델로 나뉠 수 있지요.
모델이란, '미리 만들어 놓은', '무엇인가를 나타내기 위한 샘플링'을 말합니다.
그런데 사실, 데이터가 아니라 객체입니다.
객체들이기 때문에 모델이라고 부르는 것입니다.
이녀석들을 일컬어서 프로그램 관점으로 볼 때 데이터라고 부르는 것이지요.
아무튼...
프로그램에 내용물을 쓰라고 하면 뭘 쓰겠습니까?
UI가 아닌 당연히 데이터를 쓰겠지요.
데이터는 과연 정수, 실수 이렇게 딱딱 구분지어 이루어져있을까요?
아닙니다... 객체로 이루어져 있다는 것입니다.
따라서, 객체를 썼다가 읽었다하는 경우가 필요합니다.
즉, 닷넷에서 제공하는 그대로의 직렬화 혹은 사용자 정의 직렬화를 만들어서
해당 객체가 저장될 수 있도록 할 수 있습니다.
파일을 읽어서 만드나, 데이터를 읽어서 만드나
동일해질 수 있도록 제공해주는 것이지요.
닷넷에서 가장 쉬운, 닷넷에서 제공하는 기본적인 Formatter를 사용해서
직렬화를 수행할 수 있습니다.
이를 위해서는 직렬화를 하기 위한 특성이 부여된 class가 존재해야합니다.
stream을 사용할 때 [Serializable] 특성이 부여되어있다면,
이에 따른 속성도 자동적으로 만들어집니다.
특성을 하나 부여해주는 것만으로
저장할 때에 string, int 표식이 자동으로 구성되는 것입니다.
아무튼... 형식 지정자를 통해서 형식을 만들어
직렬화를 통해 데이터를 저장할 수 있습니다.
저장할 때에는 Binary, XML, Soap이라는
세가지의 Formatter를 MS에서는 기본적으로 제공해줍니다.
즉, 이 셋은 자동으로 자신에 맞는 Format으로 자동으로 저장해주지요.
누구를 저장하고, 누구를 저장하지 않을 것인지에 대한 지정은
[Serializable] 특성이 해주게 되지요.
아무튼... 특성 부여를 통해 어떻게 저장해줄지 정해져있다는 소리입니다.
binaryFormatter는 말 그대로 간단한 바이너리 형식으로
직렬화를 제공해주는 formator이고,
XMLSerializer는 객체의 상태를 XML 문서로 저장하도록 해줍니다.
그리고, SoapFormatter의 경우 'XML+ MS의 문법'입니다.
즉, MS가 XML의 표준을 따르는 MarkUp 언어를 따로 만들었는데,
이 형식을 통해 저장해주는 Formatter라는 것입니다.
XML, Soap은 모두 Text형식의 Formatter로써,
XML은 순수 XML, Soap은 MS만의 Mark Up 언어입니다.
정리를 해보자면,
formatter는 형식을 뜻합니다.
데이터가 어떻게 보관될지에 대한 형식을 만들어준다는 것입니다.
여
물론, 사용자 Formatter도 만들 수 있습니다.
즉, 사용자 Formatter를 만들게 되면,
사용자가 구성하고 싶은데로 Format을 만들 수 있게 되지요.
binFormatter는 바이너리 형식으로써 뭔지 못알아봅니다.
그런데... 빠르지요...
하지만, XML, Soap은 Text형식으로써 뭔지 알아들을 수 있습니다.
Format안에는 데이터와 stream이 들어갑니다.
즉, 데이터가 stream에 보관되게 됩니다.
Formatter 형식에 핵심적인 함수로써,
무엇을 저장하고, 그 데이터가 어떤 식으로 저장되는지는
[Serializable] 특성이 부여되어 있는 형식만이 가능합니다.
바이너리 포멧터라면, stream에 data를 주게 되면 바이너리 형식으로,
XML 포멧터라면, XML 형식으로 만들어주는 것이지요.
stream이 네트워크와 연결되어있다면 네트워크 형식에 맞게 저장될 것이고,
파일이면 역시 파일의 형식에 맞게 저장이 될 것입니다.
따라서, 유연성이 굉장히 커지겠지요.
무수히 많은 컬렉션이 있더라도 [Serializable] 특성만 부여되어있다면
Formatter가 해석을 해줘서 stream에 그대로 저장을 해주게 됩니다.
자... 또 정리를 해봅시다...
이런 정리병.. |
직렬화를 하면 세가지의 요소가 떠올라야됩니다.
우선, 직렬화를 위한 '객체',
그리고 어디에 직렬화를 할 것인지에 대한 'stream',
마지막으로 어떻게 직렬화를 할 것인지에 대한 'Formatter'입니다.
형식이 내장 타입이 아닌 사용자 형식이라면?
[Serializable] 특성을 부여했더라도, 저장이 불가능할 것입니다.
내가 만든 타입을 Formatter가 어떻게 알겠습니까?
그래서 닷넷에서는 객체 그래프라는 개념을 사용합니다.
사용자 형식을 파고들면 '내장 형식+사용자 형식'으로 구성되어있습니다.
이 사용자 형식마다 [Serializable] 특성을 계속해서 부여해주면,
내장 형식은 어떻게 저장되는지 알 것이고
그 안에 사용자 형식도 [Serializable] 특성이 부여되어있다면 참조를 할 것입니다.
결국에 파고 들어가서 남은 사용자 형식의 안은 내장 형식 뿐이겠지요.
이렇게 객체 그래프를 통해 참조를 저장하고,
참조를 보고 또 객체 그래프를 통해 참조를 저장하는 방식을 수행합니다.
이를 통해 내부적으로 어떻게 저장하는지에 대해서 알 수 있게됬지요.
하지만, 우리가 하는 것은 아니니 걱정하지 않으셔도 됩니다.
단지, 사용자가 저장하고 싶은 타입이 [Serializable] 특성 부여가 되어있다면,
내부에 사용되는 모든 필드들이
[Serializable] 특성의 형식이어야되는 것만 기억하시길 바랍니다.
이를 해석해주는 것은 Formatter가 알아서 해주니 걱정 마시길 바랍니다.
즉, 우리는 특성만을 달아주면 된다는 소리입니다.
바이너리, Soap Formatter를 사용할 때에는 상관이없는데,
XML Formatter를 사용할 때에는
[XmlAttribute], [XmlElement]와 같은 특성을 부여해줘야합니다.
즉, 필드나 속성을 직렬화하는 데 있어서
Element로 할지, 특성으로할지 정의를 해주는 것이지요.
이전에도 언급했지만,
XML 문서를 저장할 때에는 두가지 방법으로 저장이 가능합니다.
바로, Attribute와 Element 방식이지요.
[XmlRoot] 특성도 부여해줘야합니다.
해당 특성은 XML 표준이기 때문에 해줘야합니다.
즉, 루트 요소가 생성되는 방법을 제어해주는 특성이지요.
마지막으로 사용자 직렬화를 보도록 하겠습니다.
사용자 직렬화의 핵심은 두 가지방식입니다.
예전에 특성에 대한 제공이 없을때인 구버전 방식과,
특성이라는 기능이 제공되고 난 후의 신버전 방식이 있지요.
구버전 방식을 살펴보자면...
우선, 사용자 정의 직렬화가 가능하려면 ISerializable 인터페이스를 상속받아야합니다.
그리고, GetObjectData() 메서드를 구현해야하지요.
해당 메서드는 저장하는데 사용이 되는 메서드입니다.
그리고, 생성자는 복원을 하는데 사용이 되지요.
이렇게 약속되있습니다.
ISerializable 인터페이스를 구현하고,
생성자와 GetObjectData() 메서드를 구현해야한다고 약속했다 이겁니다.
그리고 신버전 방식은 특성 세개를 사용합니다.
[Serializable], [OnSerializaing], [OnDeserialized] 특성말입니다.
[OnSerializaing] 특성은 직렬화 될 때 해당 특성이 부여된 메서드가 호출됩니다.
그리고 데이터를 읽고난 뒤 객체를 생성한 다음에
[OnDeserialized] 특성이 부여된 메서드가 호출된다 이겁니다.
해당 메서드들에서 저장하고 싶은 내용물을 지정하면 됩니다.
읽어올 때는 읽어오는 내용들의 복원데이터에 대한 정의를 만들면 된다 이겁니다.
이렇게 두가지 버전으로 사용자 직렬화 과정을 만들 수 있게 되는 것이지요.
이번 시간은 여기까지 하도록 하겠습니다.
이상 삽잡이였습니다!
'삽질의 현장 > - .NET' 카테고리의 다른 글
#084_닷넷(.NET)_ ADO.NET - ADO.NET 개념 & Provider (0) | 2015.11.16 |
---|---|
#083_닷넷(.NET)_ ADO.NET - ADO.NET Intro (0) | 2015.11.16 |
#081_닷넷(.NET)_.Net Framework 기본 - 파일(File) & 스트림(Stream) (0) | 2015.11.15 |
#080_닷넷(.NET)_.Net Framework 기본 - Thread Pool &TPL (0) | 2015.11.15 |
#079_닷넷(.NET)_.Net Framework 기본 - Thread 생성 & 동기화 (0) | 2015.11.15 |