上篇提到了读存档类库的设计,现在来谈谈实现。
加密策略容易,无非是在实现类中对字符串搞搞事情。
比如说不搞事情的版本:
public class DirectStrategy<T>:AccessStrategy<T>where T :new() { public DirectStrategy() { } public string Access(T _data,DataElememt<T> _t) { return _t.DataToFile (_data); } public T Load(string s,DataElememt<T> _t) { return _t.FileToData (s); } }直接复用了转码的结果就可以了。
如果要想随意的加加密:
public class subaddStrategy<T>:AccessStrategy<T>where T:new() { public subaddStrategy() { } public string Access(T _data,DataElememt<T> _t) { string _temp = _t.DataToFile (_data); string _result=""; for(int i=0;i<_temp.Length;i++) { int index = _temp.Length-1-i; if (index % 2 == 0) { char _tempchar = (char)((int)_temp [i] - 13); _result += _tempchar.ToString (); } else { char _tempchar = (char)((int)_temp [i] + 13); _result += _tempchar.ToString (); } } return _result; } public T Load(string s,DataElememt<T> _t) { string _real=""; for(int i=0;i<s.Length;i++) { int index = s.Length - 1 - i; if(index%2==0) { char _tempchar = (char)((int)s [i] + 13); _real += _tempchar.ToString (); } else { char _tempchar = (char)((int)s [i] - 13); _real += _tempchar.ToString (); } } return _t.FileToData (_real); } }关于转码实现类,笔者不想直接让客户端实现的数据结构直接继承我们的接口,这样封装性差。所以这里我用到了委托。
public class XMLDataTranslate<T>:DataElememt<T>where T :new() { public delegate T del1(string _s); public delegate string del2(T _t); del1 _d1; del2 _d2; public T Instance() { return new T(); } public string DataToFile(T _t) { return _d2 (_t); } public T FileToData(string _s) { return _d1 (_s); } public XMLDataTranslate(del1 d1,del2 d2) { _d1 = d1; _d2 = d2; } }用户只需要在实例化XMLDataTranslate的时候,将他们写好的方法体传入就可以了,这样用户实际是不需要关心接口细节的。
再接着是数据结构的类。
public class MyData { public int[] items; public int exp; public int rank; public int modelstate; public int favorRate; public int modelMessage; public MyData() { exp = 1; rank = 1; modelstate = 1; items = new int[1]; items[0] = 1; favorRate = 1; modelMessage = 1; } public static MyData StringtoData(string _s) { MyData _md=new MyData(); _md.exp = transtring (_s.Substring(0,4)); _md.rank = transtring (_s.Substring(4,4)); _md.modelstate = transtring (_s.Substring(8,4)); _md.favorRate = transtring (_s.Substring(12,4)); _md.modelMessage = transtring (_s.Substring(16,4)); int[] l=new int[99]; int cp = 0; for(int i=20;i<_s.Length;i+=4) { l [cp] = transtring (_s.Substring (i, 4)); cp++; } int[] cl = new int[cp]; for(int i=0;i<cp;i++) { cl [i] = l [i]; } _md.items = cl; return _md; } public static string dataToString(MyData _md) { string _result=""; _result += tranInt (_md.exp); _result += tranInt (_md.rank); _result += tranInt (_md.modelstate); _result += tranInt (_md.favorRate); _result += tranInt (_md.modelMessage); for(int i=0;i<_md.items.Length;i++) { _result += tranInt (_md.items[i]); } return _result; } public static string tranInt(int x) { string _result=""; for(int i=0;i<4;i++) { _result += (x % 10).ToString(); x /= 10; } return reverse(_result); } public static string reverse(string s) { string _result=""; for(int i=0;i<s.Length;i++) { _result += s [s.Length - 1 - i]; } return _result; } public static int transtring(string x) { int _result=0; for(int i=0;i<4;i++) { _result += int.Parse(x.Substring(i,1)) * (int)Mathf.Pow (10, 3 - i); } return _result; } }
再贴一遍完整代码:
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Xml; using System.IO; public interface DataElememt<T> where T :new() { string DataToFile(T _t); T FileToData(string _s); T Instance (); }; public class MyData { public int[] items; public int exp; public int rank; public int modelstate; public int favorRate; public int modelMessage; public MyData() { exp = 1; rank = 1; modelstate = 1; items = new int[1]; items[0] = 1; favorRate = 1; modelMessage = 1; } public static MyData StringtoData(string _s) { MyData _md=new MyData(); _md.exp = transtring (_s.Substring(0,4)); _md.rank = transtring (_s.Substring(4,4)); _md.modelstate = transtring (_s.Substring(8,4)); _md.favorRate = transtring (_s.Substring(12,4)); _md.modelMessage = transtring (_s.Substring(16,4)); int[] l=new int[99]; int cp = 0; for(int i=20;i<_s.Length;i+=4) { l [cp] = transtring (_s.Substring (i, 4)); cp++; } int[] cl = new int[cp]; for(int i=0;i<cp;i++) { cl [i] = l [i]; } _md.items = cl; return _md; } public static string dataToString(MyData _md) { string _result=""; _result += tranInt (_md.exp); _result += tranInt (_md.rank); _result += tranInt (_md.modelstate); _result += tranInt (_md.favorRate); _result += tranInt (_md.modelMessage); for(int i=0;i<_md.items.Length;i++) { _result += tranInt (_md.items[i]); } return _result; } public static string tranInt(int x) { string _result=""; for(int i=0;i<4;i++) { _result += (x % 10).ToString(); x /= 10; } return reverse(_result); } public static string reverse(string s) { string _result=""; for(int i=0;i<s.Length;i++) { _result += s [s.Length - 1 - i]; } return _result; } public static int transtring(string x) { int _result=0; for(int i=0;i<4;i++) { _result += int.Parse(x.Substring(i,1)) * (int)Mathf.Pow (10, 3 - i); } return _result; } } public class XMLDataTranslate<T>:DataElememt<T>where T :new() { public delegate T del1(string _s); public delegate string del2(T _t); del1 _d1; del2 _d2; public T Instance() { return new T(); } public string DataToFile(T _t) { return _d2 (_t); } public T FileToData(string _s) { return _d1 (_s); } public XMLDataTranslate(del1 d1,del2 d2) { _d1 = d1; _d2 = d2; } } public interface AccessStrategy<T>where T :new() { string Access(T _t,DataElememt<T> dataElements); T Load(string s,DataElememt<T> dataElements); }; public class DirectStrategy<T>:AccessStrategy<T>where T :new() { public DirectStrategy() { } public string Access(T _data,DataElememt<T> _t) { return _t.DataToFile (_data); } public T Load(string s,DataElememt<T> _t) { return _t.FileToData (s); } } public class subaddStrategy<T>:AccessStrategy<T>where T:new() { public subaddStrategy() { } public string Access(T _data,DataElememt<T> _t) { string _temp = _t.DataToFile (_data); string _result=""; for(int i=0;i<_temp.Length;i++) { int index = _temp.Length-1-i; if (index % 2 == 0) { char _tempchar = (char)((int)_temp [i] - 13); _result += _tempchar.ToString (); } else { char _tempchar = (char)((int)_temp [i] + 13); _result += _tempchar.ToString (); } } return _result; } public T Load(string s,DataElememt<T> _t) { string _real=""; for(int i=0;i<s.Length;i++) { int index = s.Length - 1 - i; if(index%2==0) { char _tempchar = (char)((int)s [i] + 13); _real += _tempchar.ToString (); } else { char _tempchar = (char)((int)s [i] - 13); _real += _tempchar.ToString (); } } return _t.FileToData (_real); } } 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; } };调用代码也很简单。
_md = new MyData (); dstrategy = new DirectStrategy<MyData> (); datatranslate = new XMLDataTranslate<MyData> (MyData.StringtoData,MyData.dataToString); _dm = new DataManager<MyData> (dstrategy,datatranslate,Application.dataPath+"/1.xml");
如果要读档的话,接着就调用_dm.read.....,存档的话,就调用_dm.write......即可。