利用状态模式CSV文件序列化

来源:互联网 发布:企业网络建设方案 编辑:程序博客网 时间:2024/06/07 01:34

  简介:

  在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.

0 0
原创粉丝点击