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

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

      初步设计信息如下:

      玩家拥有的道具信息——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读写,将转码和加密这两个部分桥接了起来,类似设计模式中的桥梁模式。其实像一个系统中的若干功能如果都能发生独立的变化,我们可以利用各自提供一个接口,最后再在总的系统中做桥接,这样子类的数量非常少,而且耦合性低。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值