zoukankan      html  css  js  c++  java
  • 代码设计简单规范 (转)

    下面这个规范是我为朋友写的几点建议,写的很范,作为BLOG,愿与大家一起分享。

    下面只给出部分设计规范样例,关于.NET编程的详细规范、设计请参考相关书籍。

    1、命名规范

    1.1    命名空间命名,一般命名为公司简称+产品名称+程序包的形式,如ARSC.EngineMap.GeometrySharpMap.FrameworkSharpMap.ControlsGoogleMap.DownloaderGoogleMap.App等,其长度一般要求不能过于太长。程序集的名称可以和命名空间保持一直。注意可以在不同的.DLL里面定义相同的命名空间。

    1.2    变量命名,如果是局部变量、函数接口变量,主要以易于表达概念的英语进行命名。单词第一个字符必须小写,如果是组合单词,第二个单词应该大写,如firstNamecomputerName

    Public void ConcactName (string firstName,string lastName);

    对于成员变量需要定义以”_”开头,如:

    Public class Person

    {

    Private string _firstName;

    Private string _lastName;

    Private int   _age;

    }

    1.3    类命名,类主要由名词性短语命名,类的第一个单词都是大写,做到见名知意,如PersonComputerExtensionManagerPrintManagerFormatTransformHttpDownloaderTcpDownloaderCommandPoolXmlHelperXmlUtilityProductFinderProductRepositoryCourseCatalog等。注意的是类命名不能加复数形式如Persons表示人的集合,正确命名应该为PersonCollection

    1.4    接口命名,接口命名可以参考类命名规则,但是其需要在命名前加”I”。如ICommandPoolIDownloaderIPrintManagerIProductFinder等。

    1.5    方法命名,主要以动名词短语构成,函数主要表达一种计算功能或者任务,因此给函数取一个合适的名字非常重要,如CaculateAreaQueryProductCreateBarExportViewCanSeekHasValueHasChildern等。长名称函数一般用于私有函数中,如CopyProductsToRepositoryFromCache这个函数要比注释好的多。

    1.6    代理命名,如提供回调的代理需要加上CallBack后缀:

    Public delegate void ProgressNotificationCallBack(int curPos,int totalSize);提供事件原型的代理需要加上EventHandler后缀,如:

    Public delegate void CurrentToolChangedEventHandler(object sender,MapToolEventArgs e);

    1.7    事件命名,主要是要能够见名知意,如

    Public event CurrentToolChangedEventHandler CurrentToolChanged;

    Public event EventHandler CurrentLayerChanged;

    1.8    属性命名,提供私有成员的访问控制如

    Public string Name

    {

         Get{return _name;}

         Set

    {

        If(value==null)

            Throw new ArgumentNullException(“Name can’t be set null.”);

        _name=value;

    }

    }

    2、成员访问控制

    成员访问控制主要由internal(在该DLL内可以访问)protected(子类可以访问)private(私有访问)public(访问不受控制)Protected internal(在其子类或者该DLL内部可以访问),我们将所有成员变量都设计成私有,如果需要公开该数据,需要提供属性。如:

    Public class Person

    {

         Private string _name;

     

        Public string Name

        {

            Get{return _name;}

            Set {_name=value;}

        }

    }

    3、XML代码注释

    对于公开函数接口必须提供代码XML注释,便于形成开发文档。私有函数可适当加以注释。详细请参考MSDN。

        /// <summary>

        /// 命令池对象,主要用于命令按钮的注册和反注册。

        /// </summary>

        ///<remarks>

        ///每一个命令池都和一个<seealso cref="ICommandBars"/>绑定在一起,

        ///如果想将按钮添加到<seealso cref="ICommandBars"/>上,首先必须在命令池中注册该按钮项目。

        ///</remarks>

        public interface ICommandPool

        {

            /// <summary>

            /// 获取命令池中工具条项目。

            /// </summary>

            /// <param name="uid">命令按钮全局唯一标识符。</param>

            /// <returns>返回工具条项目。</returns>

            ICommandItem GetCommandItem(GuidClass uid);

     

            /// <summary>

            /// 获取和设置应用程序钩子其为<seealso cref="Jackey.Framework.IApplication"/>

            /// </summary>

            object Hook { get; set; }

     

            /// <summary>

            /// 获取和设置COM对象钩子。该钩子只需要在COM应用程序中进行设置。

            /// </summary>

            object COMHookObject { get;set;}

     

            /// <summary>

            /// 获取和设置命令按钮单击回调函数。

            /// </summary>

            ButtonClickCallBack ButtonClick { get;set;}

     

            /// <summary>

            /// 利用指定全局唯一标识符注册命令按钮。

            /// </summary>

            /// <param name="cmd">命令对象。</param>

            /// <param name="guid">命令按钮全局唯一标识符。</param>

            /// <returns>返回工具条项目。</returns>

            ICommandItem RegisterCommandItem(ICommandObject cmd, GuidClass guid);

     

            /// <summary>

            /// 利用指定全局唯一标识符注册命令按钮。

            /// </summary>

            /// <param name="cmd">命令对象。</param>

            /// <param name="cmdType">工具条项目类型</param>

            /// <param name="guid">命令按钮全局唯一标识符。</param>

            /// <returns>返回工具条项目。</returns>

            ICommandItem RegisterCommandItem(ICommandObject cmd, CommandTypeEnum cmdType, GuidClass guid);

     

            /// <summary>

            /// 从配置文件中注册所有已配置的命令按钮项目。

            /// </summary>

            /// <param name="exeConfigPath">配置文件路径</param>

            void RegisterCommandItemFromConfiguration(string exeConfigPath);

     

            /// <summary>

            /// 注销所有命令按钮。

            /// </summary>

            void UnRegisterAll();

     

            /// <summary>

            /// 注销指定全局唯一标识符的命令项目。

            /// </summary>

            /// <param name="cmdID">命令按钮全局唯一标识符。</param>

            void UnRegisterCommandItem(GuidClass cmdID);

     

    }

    再如:

    /// <summary>

        ///XML文件中提取工具条和按钮,动态生成系统菜单,菜单生成算法存储于菜单生成指导者类.

        /// </summary>

        public class XmlCommandBuilder:ICommandBuilder

        {

            #region private and protected members

     

            private ICommandBars iCmdBars;

            private List<ICommandBar> _cmdBarList;

     

            /// <summary>

            /// xml document.

            /// </summary>

            protected XmlDocument _document;

     

            /// <summary>

            /// tool bar item command id.

            /// </summary>

            protected readonly static string COMMAND_ITEM_GUID = "commandid";

     

            #endregion

     

            /// <summary>

            /// 构造函数。

            /// </summary>

            /// <param name="xmlConfigPath">工具条配置文件路径。</param>

            /// <param name="cmdBars">工具条管理器接口。</param>

            /// <exception cref="System.ArgumentNullException">xmlConfigPath为空抛出该异常。</exception>

            /// <exception cref="System.ArgumentNullException">cmdBars为空抛出该异常。</exception>

            public XmlCommandBuilder(string xmlConfigPath,ICommandBars cmdBars)

            {

                if (String.IsNullOrEmpty(xmlConfigPath))

                    throw new ArgumentNullException("xmlConfigPath can't be null or empty.");

     

                if (cmdBars == null)

                    throw new ArgumentNullException("cmdBars can't be null.");

     

                this.iCmdBars = cmdBars;

                _document = new XmlDocument();

                _document.Load(xmlConfigPath);

            }

    }

    4、标准模式设计

    4.1标准IDispoable模式设计

    对于具有非托管资源,如文件指针、数据库连接、套接字等必须实现标准IDisposable模式。对于组合实现IDisposable的类也应该实现IDisposable模式。

    下面是一个标准实现IDisposable的类。

     

    public class BaseClass:IDisposable

        {

            private FileStream _readStream;

            private FileStream _writeStream;

            protected bool _disposed;

     

            //如果该类没有非托管资源则注释该终结器函数,该函数的添加会从一定

            //程度上损伤程序性能。

            ~BaseClass()

            {

                this.Dispose(false);

            }

     

            //允许子类重写该函数。

            protected virtual void Dispose(bool disposing)

            {

                if (!_disposed)

                {

                    if (disposing)

                    {

                        //这里释放托管资源

     

                        if (_readStream != null)

                            _readStream.Dispose();

     

                        if (_writeStream != null)

                            _writeStream.Dispose();

                    }

     

                    //这里释放非托管资源

                    //do something release unmanaged resources.

     

                    _disposed = true;

                }

            }

     

            public void Dispose()

            {

                this.Dispose(true);

                GC.SuppressFinalize(this);

            }

     

    }

    public class DerivedClass:BaseClass

        {

            private FileStream _myStream;

     

            //如果该类没有非托管资源则注释该终结器函数,该函数的添加会从一定

            //程度上损伤程序性能。

            ~DerivedClass()

            {

                this.Dispose(false);

            }

     

            public void ReadNextChunk()

            {

                if (_disposed)

                    throw new ObjectDisposedException("object has been disposed.");

                //do the real thing.

            }

            protected override void Dispose(bool disposing)

            {

                if (!_disposed)

                {

                    try

                    {

                        if (disposing)

                        {

                            //这里释放托管资源

     

                            if (_myStream != null)

                                _myStream.Close();

                        }

     

                        //这里释放非托管资源

                    }

                    finally

                    {

                        base.Dispose(disposing);

                    }

     

                    //这句可以不加。

                    _disposed = true;

                }

            }

    }

     

    5、.Net开发几点性能和设计问题的建议:

    5.1 避免在一个大的循环里面执行装箱和拆箱操作。解决办法是利用泛型如List<T>取代ArrayList

    ArrayList list = new ArrayList();

       for (int i = 0; i < 10000;i++ )

    {

                    //装箱

                    list.Add(i);

     

                    //拆箱

                    Debug.WriteLine(list[i].ToString());

    }

    5.2 对于复杂的事件交互的系统,在每个类被终结前确保其已经注销所有事件。否则及易发生内存泄露。这种情况在.NetCOM互操作中经常出现,如ArcObject的各种事件。

    5.3 对于工具类如WorkspaceHelper(封装AO的工作空间操作的类)应该做到简单和易于理解,不要把HelperUtility类当作大杂烩,什么方法都往里面放,这将导致代码非常难以修改。工具类的方法大都为静态方法,该类也为静态类。尽量不要把类设计为静态类,一旦设计成静态类,将无法利用多态的优势。

  • 相关阅读:
    VS2010制作网站自定义安装程序 转
    SQL Express几个版本的区别
    WebGIS(PostgreSQL+GeoServer+OpenLayers)之二 GeoServer安装与数据配置
    CentOS设置ipv4和ipv6
    Linux下Vim的启动与退出
    Linux字符界面基本操作
    CentOS字符界面与图形界面的切换
    mysql显示SQL语句执行时间
    将shp文件导入到mysql数据库中
    MySQL导入sql 文件的5大步骤
  • 原文地址:https://www.cnblogs.com/footleg/p/1159357.html
Copyright © 2011-2022 走看看