国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

[原]實例-簡單設計&精簡代碼&復用代碼

2019-11-17 02:39:43
字體:
來源:轉載
供稿:網友

[原]實例-簡單設計&精簡代碼&復用代碼

引言

本文以實際項目為例談一談我個人對于軟件開發的理解,偏細節軟件項目B基于.net平臺,使用WPF框架,c#語言,MVVM模式開發的桌面軟件該軟件支持可視化的設計器功能,允許所見即所得的方式為頁面添加文字、圖像等元素。可對元素進行編譯解析,生成對應的二進制數據下發至下位機,本文不對軟件整體設計做介紹,僅列舉部分設計及編碼細節進行介紹

獨立的Model層數據類型

Model層作為獨立的數據訪問層,數據類型定義保持獨立,僅記錄數據本身,ui無關結構如下圖BGPRoject 項目類型,組合多個BGDiargam視圖對象BGDiagram視圖類型,組合多個BGElement元素對象,存在多個派生元素類型View層在使用數據時,可封裝視圖數據類型組合Model數據類型,以記錄其他UI相關數據

適度封裝以簡化代碼

編譯過程需對文字、圖片等做不同處理初期實現時僅實現了一個TextCompiler,后續陸續實現ImageCompiler等,遂提取抽象基類CompilerBase形成如下結構Compile方法由各個派生類自行實現編譯邏輯上層編譯邏輯的實現,簡單使用多態,如下
    public bool Compile(BGProject project, out String errorMessage)    {        TextCompiler textCompiler = new TextCompiler(project);        ImageCompiler imageCompiler = new ImageCompiler(project);        XxxCompiler xxxCompiler = new XxxCompiler(project);        foreach (CompilerBase compiler in            new CompilerBase[] {textCompiler, imageCompiler, XxxCompiler})        {            compiler.Compile();            if (!compiler.Validate(out errorMessage))            {                return false;            }        }                // ...    }

Don't Repeat Yourself 復用代碼

每一種數據的編譯邏輯中,都需要遍歷相應類型的元素,因此考慮將元素遍歷邏輯獨立出來為基類TravelCompilerBase添加如下方法
        protected static void TravelElements<T>(BGProject project, BGElementType elementType, Action<T> action)            where T : BGElement        {            foreach (BGDiagram diagram in project.Diagrams)            {                foreach (T element in                    diagram.Elements.Where(e => e.ElementType == elementType))                {                    action(element);                }            }        }
處理邏輯通過action參數傳遞進來TextCompiler中編譯文字元素時,調用上述方法,通過lambda表達式生成匿名方法完成處理邏輯
            TravelElements<BGTextElement>(Project, BGElementType.Text,                                          element =>                                              {                                                  //.... 針對目標元素做相應處理                                              });

處理該特定問題,這里使用委托的方式,泛型化使其易于使用,你也可以使用TemplateMethod模式

合宜地使用靜態類型封裝基本工具類型

靜態類型是一種良好組織獨立工具method的方式許多不專業的程序員常將靜態類型作為存儲全局對象的容器,這其實是在破壞軟件結構。應盡一切可能避免使用靜態類型變量

序列化工具類

項目中涉及數據序列化到本地文件,直接使用如下工具類型

    public static class SerializeUtility    {        public static void BinarySave<T>(String filePath, T obj)        {            using (Stream stream = new FileStream(filePath, FileMode.Create, Fileaccess.Write, FileShare.None))            {                IFormatter formatter = new BinaryFormatter();                formatter.Serialize(stream, obj);            }        }        public static T BinaryLoad<T>(String filePath)        {            return BinaryLoad<T>(filePath, null);        }        public static T BinaryLoad<T>(String filePath, SerializationBinder serializationBinder)        {            if (!File.Exists(filePath))            {                return default(T);            }            using (Stream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None))            {                IFormatter formatter = new BinaryFormatter();                if (serializationBinder != null)                {                    formatter.Binder = serializationBinder;                }                return (T)formatter.Deserialize(stream);            }        }    }

int與byte數組轉換工具類

涉及到傳輸數據至下位機,考慮數據存儲格式,編寫如下工具類,支持littleEnding與bigEnding

    // Created by Ant 2014-4-30    public static class BytesConverterUtility    {        public static byte[] GetBytes(int value, int length, bool isLittleEndian = true)        {            if (value < 0)            {                throw new ArgumentException("value不能為負數");            }            if (length > 4)            {                throw new ArgumentException("length不能>4");            }            var rawBytes = BitConverter.GetBytes(value);            if (rawBytes.Length < length)            {                throw new applicationException(                    String.Format("BitConverter.GetBytes返回的字符數{0}小于目標字符數{1}", rawBytes.Length, length));            }            var bytes = new byte[length];            if (BitConverter.IsLittleEndian != isLittleEndian)            {                Array.Reverse(rawBytes);                Array.Copy(rawBytes, rawBytes.Length - length,                           bytes, 0, length);            }            else            {                Array.Copy(rawBytes, bytes, length);            }            return bytes;        }        public static int ToInt(byte[] bytes, int offset, int length, bool isLittleEndian = true)        {            if (length == 1)            {                return bytes[offset];            }            var tempBytes = new byte[length];            Array.Copy(bytes, offset, tempBytes, 0, length);            if (!isLittleEndian)            {                Array.Reverse(tempBytes);            }            switch (length)            {                case 2:                    // 特殊處理,轉換為無符號int類型,返回時自動轉換為Int32                    return BitConverter.ToUInt16(tempBytes, 0);                case 4:                    // 注意,這里將數據轉換為有符號int類型                    return BitConverter.ToInt32(tempBytes, 0);                default:                    throw new ArgumentException("length 長度非標準值");            }        }    }

工具類型的方便之處在于其獨立性,幾乎無外部依賴,不需要考慮對其進行初始化,拿來就可以直接使用


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 宾阳县| 丹阳市| 府谷县| 阜平县| 上虞市| 县级市| 大竹县| 潍坊市| 金堂县| 锡林郭勒盟| 芦溪县| 宜章县| 淮滨县| 迁安市| 霍山县| 永吉县| 彰武县| 城步| 东方市| 舒城县| 贵溪市| 呼图壁县| 日土县| 洪泽县| 马尔康县| 金寨县| 诏安县| 上林县| 封丘县| 博兴县| 辽宁省| 黑山县| 阳朔县| 旬阳县| 重庆市| 惠来县| 旺苍县| 宕昌县| 武安市| 丰台区| 奈曼旗|