[C#.NET] 利用 泛型方法 重構 反序列化

  • 11760
  • 0
  • 2012-01-09

[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);
}

 

執行結果如下:

image

 

在用戶端程式,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));
}

執行結果如下:

image

 

類別圖關係如下:

image

 


我覺得在用戶端擁有太多的邏輯判斷,未來若有需求變更,這裡可能會有影響,為了遵守開放-封閉原則,我決定將這些判斷移到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));
}

 

執行結果如下:

image

 

類別圖關係如下:

image

 


後記:

1.類別圖若有誤請告知

2.本次重構依照了開放-封閉及依賴倒轉原則,將判斷分支由用戶端程式碼抽離,離成功的重構之路越來越近。

若有謬誤,煩請告知,新手發帖請多包涵


Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET

Image result for microsoft+mvp+logo