上篇提到了讀存檔類庫的設計,現在來談談實現。
加密策略容易,無非是在實現類中對字符串搞搞事情。
比如說不搞事情的版本:
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......即可。