利用狀態模式CSV文件序列化

  簡介:

  在unity3d中可以使用使用繼承自scriptObject類並添加CreateAssetMenu屬性方便實現類的序列化,但值得注意的是這種方式並不支持程序打包之後數據的保存。

  當然常用的還有xml和json的方式來保存類的信息,在需要的時候加載出來,這方面就不多說了。但是直觀的來說,表最適合一些簡單的數據類型的記錄,鍵值對最簡單。

  特別是一個一些程序的配製或者標題對應於一段富文本來說,這樣的信息最適合保存在csv文件中。

  狀態模式:(例1

  面對象常的設計模式中,狀態模式比較常用的一種。一個類的某個屬性有多種狀態,而這個類實現通用的方法,在不同的狀態下會產生不同的後果,不同的狀態分別抽象爲一個個獨立的類,其內部可以觸發整體狀態的改變。只需要考慮到不同狀態下具體的實現和狀態的轉換,而大大簡化了用戶調用的接口。

  CSV文件:(例2

  利用excel,可以進行csv文件的編輯,可以方便的將只包含文字信息的表格導出爲csv文件,並且可以進行重複編輯。

  程序中要使用csv,先要將其文本文件的格式進行透徹分析。

  測試一、 先建立一個簡單的表格如圖所示(沒有引號):

 

   然後利用notepad打開可以看到下面這樣的格式:

  id,name,sex

  這種情況下,要解析實在是太容易了,要什麼設計模式...

  測試二、填寫一些複雜的數據試試(有引號):

 

  notepad打開:

  id,name,sex
  1,小名:"小藝",girl
 這種情況下,貌似也不太複雜,只要用“,”分解不就好了?

 測試三、更爲複雜的信息:

 

  notepad打開試試:

  id,name,sex
  1,"小名:""小藝"",大名:""楊彬藝""",girl

  這下壞了,直接用,分解是不可能的,特別是對於更爲複雜的一大段文字信息。
  測試四、段內還有換行呢!

 

  notepad內信息如下:

  id,name,sex
1,"小名:""小藝""
大名:""楊彬藝""",girl

真的換行了哦,原來以爲可以readline就可以讀取出一組數據的方式也行不通了...

  程序接口設計:

  要將程序設計爲通用易用,不得不遵循接口隔離的原則,儘量簡化類的接口。要實現程序的面對象特性,還要將每個類的功能設計得相對單一,以降低類之前的偶合。

  首先設計的最,最外層CsvLoaderManager,這應該是一個單例,方便全局使用並且能使用一些MonoBehaiver的方法,其主要的功能就是加載和保存csv文件。

  其次要設計的,ParserCSV,其主要的功能是將csv文本信息轉換爲一個二維數組。

  然後設計的是一個狀態機ParserStateMachine,讀取遇到的一個字符信息。


public class ParserStateMachine
{
    public LineStartState LineStartState;
    public ValueStartState ValueStartState;
    public ValueState ValueState;
    public QuotedValueState QuotedValueState;
    public QuoteState QuoteState;

    private ParserState currState;
    public ParserContext context;
    public const char CommaCharacter = ',';
    public const char QuoteCharacter = '"';
    public bool TrimTrailingEmptyLines;
    public int MaxColumnsToRead;
    public ParserStateMachine(bool TrimTrailingEmptyLines = false,int MaxColumnsToRead = 0)
    {
        this.TrimTrailingEmptyLines = TrimTrailingEmptyLines;
        this.MaxColumnsToRead = MaxColumnsToRead;
        context = new global::ParserContext();
        LineStartState = new LineStartState(this);
        ValueStartState = new ValueStartState(this);
        ValueState = new ValueState(this);
        QuotedValueState = new QuotedValueState(this);
        QuoteState = new QuoteState(this);
    }

    public void SetState(ParserState currState)
    {
        this.currState = currState;
    }

    public void AnyChar(char ch)
    {
        currState.AnyChar(ch);
    }

    public void Comma()
    {
        currState.Comma();
    }

    public void EndOfLine()
    {
        currState.EndOfLine();
    }

    public void Quote()
    {
        currState.Quote();
    }
}


  然後是抽象的狀態類ParserState,和具體的LineStartState,ValueStartState,ValueState,QuotedValueState,QuoteState 這五種狀態(分別是換行狀態、值開始狀態、值狀態、引號內值狀態、引號狀態);

  最後是將二得到的二維數據轉換爲具體的類的,因爲每個類者有相似的轉換方法,可以寫一個模板類,用編輯器擴展生成一個具體的類並繼承於一個抽象的CSVTable。

  以上的狀態模式只適用於數據加載到具體類中,要實現一個將數據轉換爲csv信息的方式,並不是簡單的反過來寫就行。

  具體實現參見github上的源碼吧

 https://github.com/zouhunter/CSVConfig


  注意事項:

  1、 csv文件利用excel打開之後格式會發生變化,程序中使用時,需要提前將格式轉換爲UTF_8.

發佈了32 篇原創文章 · 獲贊 12 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章