오늘은 직렬화를 이용해 C#으로 만든 TextRPG 게임을 저장하여, 껐다 켜도 정보가 유지되도록 만들 것이다.
먼저 직렬화가 무엇인지 알아보자
<직렬화란?>
컴퓨터 과학의 데이터 스토리지 문맥에서 데이터 구조나 오브젝트 상태를 동일하거나 다른 컴퓨터 환경에 저장(이를테면 파일이나 메모리 버퍼에서, 또는 네트워크 연결 링크 간 전송)하고 나중에 재구성할 수 있는 포맷으로 변환하는 과정이다.
오브젝트를 직렬화하는 과정은 오브젝트를 마샬링한다고도 한다. 반대로, 일련의 바이트로부터 데이터 구조를 추출하는 일은 역직렬화(Deserialization)라고 한다.
위 내용은 위키백과에 나와있는 직렬화의 정의인데, 간단하게 요약하면
객체를 통신하기 쉬운 포맷으로 변환하여 저장하는 과정이다.
*역직렬화는 반대로 디스크에 저장한 데이터를 읽거나, 네트워크 통신으로 받은 데이터를 메모리에 쓸 수 있도록 다시 변환하는 것이다.

그렇다면 왜 직렬화를 사용할까?
직렬화를 사용하는 이유는 크게 두가지가 있다.
첫째, 시스템이 종료되더라도 없어지지 않는 영속화된 데이터이기 때문이다.
둘째, 필요할 때 직렬화된 객체 데이터를 가져와서 역직렬화하여 객체를 바로 사용할 수 있게 된다.
나는 이 특성들을 이용하여 게임의 저장과 불러오기 기능을 수행하도록 할 것이다.
.NET 환경에서 제공되는 직렬화를 하는 방식은 여러가지가 존재한다.
이 중에서 XML 직렬화를 사용해서 게임의 정보를 저장해보자.
<XML Serialization>
XML Serialization은 클래스 객체 테이터를 XML 포맷으로 저장하는데, 주의할 점은 public 멤버 만 저장한다. 즉, public이 아닌 필드 / 속성은 저장하지 않는다. 따라서 Serialization할 클래스는 public으로 선언해야 하며, Deserialization을 위해 파라미터가 없는 생성자를 가져야 한다.
<예시> : Item 클래스를 저장해보자
public class Item { public string name { get; set; } public string type { get; set; } public int stat { get; set; } public string description { get; set; } public bool equipState { get; set; } public int price { get; set; } public Item() { name = ""; type = ""; stat = 0; description = ""; equipState = false; price = 0; } public Item(string _name, string _type, int _stat, string _description, int _price) { name = _name; type = _type; stat = _stat; description = _description; price = _price; } // 아이템의 정보를 보여주는 클래스 public void ItemInfo() { // 내용 생략 } // 아이템을 장착하거나 해제할 때 사용하는 함수 public void Equip(Player player, Item item) { // 내용 생략 } // xml파일로 클래스의 멤버변수를 저장 public void Save(string fileName) { using (var stream = new FileStream(fileName, FileMode.Create)) { var XML = new XmlSerializer(typeof(Item)); XML.Serialize(stream, this); } } } static void Main(string[] args) { // 아이템 생성 Item noviceArmor = new Item("수련자갑옷", "방어구", 5, "수련에 도움을 주는 갑옷입니다.", 1000); // xml파일로 저장 noviceArmor.Save("test.xml"); }
이런식으로 코드를 짜면 Main문에서 Item 클래스인 수련자의 갑옷이라는 아이템이 생성된다. 그리고 Item 클래스의 멤버변수 데이터들이 "test.xml" 이라는 이름을 가진 xml파일로 저장된다.

이제 이 xml파일을 불러와서 적용시켜 보자.
<예시> : Item 클래스를 불러와보자
public class Item { public string name { get; set; } public string type { get; set; } public int stat { get; set; } public string description { get; set; } public bool equipState { get; set; } public int price { get; set; } public Item() { name = ""; type = ""; stat = 0; description = ""; equipState = false; price = 0; } public Item(string _name, string _type, int _stat, string _description, int _price) { name = _name; type = _type; stat = _stat; description = _description; price = _price; } // 아이템의 정보를 보여주는 클래스 public void ItemInfo() { // 내용 생략 } // 아이템을 장착하거나 해제할 때 사용하는 함수 public void Equip(Player player, Item item) { // 내용 생략 } // xml 파일로 클래스의 멤버변수를 저장 public void Save(string fileName) { using (var stream = new FileStream(fileName, FileMode.Create)) { var XML = new XmlSerializer(typeof(Item)); XML.Serialize(stream, this); } } // xml 파일 불러오기 public static Item LoadFromFile(string fileName) { using (var stream = new FileStream(fileName, FileMode.Open)) { var XML = new XmlSerializer(typeof(Item)); return (Item)XML.Deserialize(stream); } } } static void Main(string[] args) { // 아이템 생성 Item noviceArmor = Item.LoadFromFile("test.xml"); }
아까와 다르게 Item 클래스에 LoadFromFile()이라는 함수가 생겼는데, 해당 함수는 클래스가 저장된 xml파일을 불러오는 함수이다. Main문에서 수련자의 갑옷을 LoadFromFile() 함수를 통해 test.xml 파일에 저장된 멤버변수 데이터를 불러오면 아래와 같이 잘 적용되는 모습을 볼 수 있다.
