[C#.NET] 利用 泛型方法 重構 反序列化
我利用類別屬性把資料存成*.xml檔案,再利用反序列化將*.xml檔案讀回來所以我會有兩個類別
public class Company
{
public string Name { get; set; }
public string Address { get; set; }
}
public class Family
{
public string Father { get; set; }
public string Mother { get; set; }
}
然後建立 SerializeToXml 靜態方法將類別存成xml檔,用DeserializeFromXml將xml檔案轉成類別。
public class XmlSerialize
{
public static void SerializeToXml(string FileName, object Object)
{
XmlSerializer xml = null;
Stream stream = null;
StreamWriter writer = null;
try
{
xml = new XmlSerializer(Object.GetType());
stream = new FileStream(FileName, FileMode.Create, FileAccess.Write, FileShare.Read);
writer = new StreamWriter(stream, Encoding.UTF8);
xml.Serialize(writer, Object);
}
catch (Exception ex)
{
throw ex;
}
finally
{
writer.Close();
stream.Close();
}
}
public static object DeserializeFromXml(string FileName, object Object)
{
if (!File.Exists(FileName))
return null;
XmlSerializer xml = null;
Stream stream = null;
StreamReader reader = null;
object obj = null;
try
{
xml = new XmlSerializer(Object.GetType());
stream = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.None);
reader = new StreamReader(stream, Encoding.UTF8);
obj = xml.Deserialize(reader);
return obj;
}
catch (Exception ex)
{
throw ex;
}
finally
{
reader.Close();
stream.Close();
}
}
}
在用戶端程式,將類別轉成xml檔
private void button1_Click(object sender, EventArgs e)
{
Company company = new Company() { Name = "有良心企業", Address = "地球村" };
Family family = new Family() { Father = "阿福", Mother = "阿娘" };
XmlSerialize.SerializeToXml("company.xml", company);
XmlSerialize.SerializeToXml("family.xml", family);
}
執行結果如下:
在用戶端程式,xml檔轉成類別
private void button2_Click(object sender, EventArgs e)
{
Company company = null;
Family family = null;
object oCompany = XmlSerialize.DeserializeFromXml("company.xml", new Company());
object oFamily = XmlSerialize.DeserializeFromXml("family.xml", new Family());
if (oCompany is Company)
company = oCompany as Company;
if (oFamily is Family)
family = oFamily as Family;
Console.WriteLine(string.Format("名稱:{0},位置:{1}", company.Name, company.Address));
Console.WriteLine(string.Format("爸爸:{0},媽媽:{1}", family.Father, family.Mother));
}
執行結果如下:
類別圖關係如下:
我覺得在用戶端擁有太多的邏輯判斷,未來若有需求變更,這裡可能會有影響,為了遵守開放-封閉原則,我決定將這些判斷移到XmlSerialize.DeserializeFromXml方法裡做,我將利用泛型方法直接回傳正確的型別
所以我將方法改裝一下
public static T DeserializeFromXml<T>(string FileName)
{
XmlSerializer xml = null;
Stream stream = null;
StreamReader reader = null;
try
{
xml = new XmlSerializer(typeof(T));
stream = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.None);
reader = new StreamReader(stream, Encoding.UTF8);
object obj = xml.Deserialize(reader);
if (obj == null)
return default(T);
else
return (T)obj;
}
catch (Exception ex)
{
throw ex;
}
finally
{
stream.Close();
reader.Close();
}
}
如此一來在用戶端的程式碼則改成,用戶端的程式碼看起來相當的簡潔,沒有多餘的邏輯判斷,成功的將邏輯層跟UI層分開
private void button3_Click(object sender, EventArgs e)
{
Company company = XmlSerialize.DeserializeFromXml<Company>("company.xml");
Family family = XmlSerialize.DeserializeFromXml<Family>("family.xml");
Console.WriteLine(string.Format("名稱:{0},位置:{1}", company.Name, company.Address));
Console.WriteLine(string.Format("爸爸:{0},媽媽:{1}", family.Father, family.Mother));
}
執行結果如下:
類別圖關係如下:
後記:
1.類別圖若有誤請告知
2.本次重構依照了開放-封閉及依賴倒轉原則,將判斷分支由用戶端程式碼抽離,離成功的重構之路越來越近。
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET