[音之国度读存档]设计篇

xiaoxiao2021-02-28  78

      项目音之国度用到了读存档,需要把一些运行时要用到的信息存起来。

      初步设计信息如下:

      玩家拥有的道具信息——int类型的索引数组。

      玩家当前经验值——int。

      玩家当前等级——int。

      音符兽的形态——int。

      音符兽对主人的好感度——int。

      当前拥有的是哪些音符兽——int。

      初步计划是编写一个可拓展性很强的类库,因为读存档的信息太容易变化了。

      理一理思路,其实能够发现,一共三步,将数据结构的信息全转成string——加密string——利用XML将string存起来(反向加载的时候亦然)。

      很容易得知,类库中比较易变的是第一步转码(因为会因为要存储的信息不一样而改变),第二步加密,因为不同的策略而改变方法。

      所以我们首先抽象出一个泛型接口DataElement<T>:

public interface DataElememt<T> where T :new() { string DataToFile(T _t); T FileToData(string _s); T Instance (); };

再来就是加密策略接口,不同的策略将在实现类延迟实现:

public interface AccessStrategy<T>where T :new() { string Access(T _t,DataElememt<T> dataElements); T Load(string s,DataElememt<T> dataElements); };      接下来我们会发现具体实现数据读存档的类已经可以写了:

public class DataManager<T>where T :new() { AccessStrategy<T> _Strategy; string _file; DataElememt<T> _dataElement; public DataManager(AccessStrategy<T> strategy,DataElememt<T> dataElement,string file) { _Strategy = strategy; _file = file; _dataElement = dataElement; } public void Write(int _index,T _t) { XmlDocument xml_doc=new XmlDocument(); string _tempMessage = _Strategy.Access (_t,_dataElement); if (File.Exists (_file)) { xml_doc.Load (_file); XmlNodeList list_node=xml_doc.SelectSingleNode ("GAMEFILE").ChildNodes; bool isHaveIndex=false; string[] all_data=new string[list_node.Count]; string[] all_index = new string[list_node.Count]; int cp = 0; int cl = 0; foreach(XmlElement xn in list_node) { if (xn.InnerText == _index.ToString ()) { isHaveIndex = true; cl = cp; } all_data [cp] = xn.GetAttribute ("data"); all_index[cp] = xn.Name; cp++; } if (isHaveIndex) { xml_doc = new XmlDocument (); XmlElement Top_ELEMENT = xml_doc.CreateElement ("GAMEFILE"); xml_doc.AppendChild (Top_ELEMENT); for(int i=0;i<cp;i++) { if (i != cl) { XmlElement xe = xml_doc.CreateElement ("FILEDATA"); xe.InnerText = all_index [i].ToString (); xe.SetAttribute ("data",all_data[i]); xml_doc.FirstChild.AppendChild (xe); } } } } else { XmlElement Top_ELEMENT = xml_doc.CreateElement ("GAMEFILE"); xml_doc.AppendChild (Top_ELEMENT); } XmlElement xe1 = xml_doc.CreateElement ("FILEDATA"); xe1.InnerText = _index.ToString (); xe1.SetAttribute ("data", _tempMessage); xml_doc.FirstChild.AppendChild (xe1); xml_doc.Save (_file); } public void Clear() { XmlDocument xml_doc=new XmlDocument(); xml_doc.Save (_file); } public T Read(int _index) { XmlDocument xml_doc=new XmlDocument(); xml_doc.Load (_file); T _result = _dataElement.Instance (); XmlNodeList list_node=xml_doc.SelectSingleNode ("GAMEFILE").ChildNodes; foreach(XmlElement xn in list_node) { if (int.Parse (xn.InnerText) == _index) { string _temp; _temp = xn.GetAttribute ("data"); _result = _Strategy.Load (_temp, _dataElement); break; } } return _result; } };组合了转码类和加密类,这个类实际上就是利用xml读写,将转码和加密这两个部分桥接了起来,类似设计模式中的桥梁模式。其实像一个系统中的若干功能如果都能发生独立的变化,我们可以利用各自提供一个接口,最后再在总的系统中做桥接,这样子类的数量非常少,而且耦合性低。

转载请注明原文地址: https://www.6miu.com/read-22028.html

最新回复(0)