编程规约--面向对象的方法该如何写

来源:互联网 发布:北京网络职业学校贴吧 编辑:程序博客网 时间:2024/06/15 00:29

   常见的编程规约中多数只是定义了,大小写,命名规则..代码格式等等.但是却很少有规约介绍如何写面向对象的方法..

面向过程的方法函数很是简单.只要遵循一个准则.即一致性..一个函数的作用永远是一样的.. 传递的参数相同,则结果肯定是相同的.

无论在哪里使用,怎么使用运行结果都是一样的..

下面是易读, 易修改 的代码: 缺点是不好用,需要学习很多知识才能上手.达不到9分猜1分查手册 就能写代码的效果

例如:

int add(a,b)

{

return a+b;

}

add(1,2)的结果永远是3;无论你在哪里调用.   


 我读过不少烂代码,更改过不少烂代码...


发现最容易读最容易理解的是c语言的那种,一个方法一个方法的去运行的,面向过程的源代码.
但是这种面向过程的代码虽然说好读,但是不好用... 

比如我们c++语言中,创建一个窗口的代码:

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprevInstance,LPSTR lpCmdLine,int nComShow){WNDCLASS wndcls;wndcls.cbClsExtra=0;wndcls.cbWndExtra=0;wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);wndcls.hInstance=hInstance;wndcls.lpfnWndProc=WinSunProc;wndcls.lpszClassName="sunxin2010";wndcls.lpszMenuName=NULL;wndcls.style=CS_HREDRAW | CS_VREDRAW;RegisterClass(& wndcls);HWND hwnd;hwnd=CreateWindow("sunxin2010","http://www.lineage2.com.cn",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,hInstance,NULL);ShowWindow(hwnd,SW_SHOWNORMAL);UpdateWindow(hwnd);MSG msg;while(GetMessage(&msg,NULL,0,0)){  TranslateMessage(&msg);  DispatchMessage(&msg);} return 0;}


第一步必须先 RegisterClass.

第二步还得    CreateWindow

第三步才是   ShowWindow

悲剧的是还有第四步  UpdateWindow 

如果你想让系统有反应,还的加上下面的while消息循环.

可能有人会说了,"这个是必然的...你肯定是不懂window的系统底层原理...这种代码习惯了就好用...." 是的,你说的没错,我c++不专业,更没写过几个c++的代码...


这个代码是很容易懂的.但是.....问题是,如果你没学习过这个操作系统底层..这个代码你很难自己空手写出来...如果你天天写另当别论..我讨论的是完全的新手


好.上面说的是这种面向过程的函数式的代码...易读, 易修改的代码:,缺点是不好用,需要学习很多知识才能上手.达不到9分猜1分查手册 就能写代码的效果

下面在说说.另外一种代码风格面向对象的代码... 

众所周知,面向对象的代码一个最大的特点就是,动态方法是属于某个对象的..而不是属于整个程序的..不同对象调用同一个方法所返回的结果,不一定是相同的..

 

/// <summary>        /// 解析自定义标签内容        /// </summary>        protected void ParseLabelConetent()        {            string pattern = @"\[unLoop,[^\]]+\][\s\S]*?\[/unLoop\]|\[Loop,[^\]]+\][\s\S]*?\[/Loop\]";            Regex reg = new Regex(pattern, RegexOptions.Compiled);            string content = LabelContent; //LabelContent 从哪里来?            Match m = reg.Match(content);            while (m.Success)            {                string mass = m.Value.Trim();                LabelParse labelparse = new LabelParse(mass);                labelparse.ParseContent();     //bad 风格不好的方法使用方式, 应当把这个方法归并到Parse中...这样用的时候就会很简单.很易懂..                                string s = labelparse.Parse();                content = content.Replace(mass, s);                m = reg.Match(content);            }            this._FinalHtmlCode = content;    //bad  风格不好的使用方式..应该直接return 这个content                }


上面这段代码里面最后一行,
this._FinalHtmlCode = content; 就修改了对象的属性...
用的时候是怎么用的呢?
        /// <summary>        /// 生成最终的HTML代码        /// </summary>        public override void MakeHtmlCode() //真是悲剧... 这个名字在这种情况下可以不要        {            ParseLabelConetent();         }

像这样的代码是很难读懂的...我们在没看到ParseLabelConetent源代码的时候,我们不知道下面怎么用,里面产生了什么变化.做了那些内容..处理了那些数据...这样的方法虽然也能运行..但是阅读起来是很困难的..而且更要命的是修改起来更麻烦..因为你必须一个方法一个方法的全部看过以后,才知道那些是必须修改的...一个好的方法应该是看到函数名,就知道这个方法是干什么用的.会修改对象的那些属性.这是必要的条件之一..第二个应该满足的条件就是...函数尽量的静态私有化..为什么呢?静态的好处就是像c语言那样好读例如我们下面修改后的代码:
                /// <summary>        /// 解析自定义标签内容        /// </summary>        private static string ParseLabelConetent(string LabelContent)        {            string pattern = @"\[unLoop,[^\]]+\][\s\S]*?\[/unLoop\]|\[Loop,[^\]]+\][\s\S]*?\[/Loop\]";            Regex reg = new Regex(pattern, RegexOptions.Compiled);            string content = LabelContent; //LabelContent 从哪里来?            Match m = reg.Match(content);            while (m.Success)            {                string mass = m.Value.Trim();                LabelParse labelparse = new LabelParse(mass);                labelparse.ParseContent();     //bad 风格不好的方法使用方式, 应当把这个方法归并到Parse中...这样用的时候就会很简单.很易懂..                                string s = labelparse.Parse();                content = content.Replace(mass, s);                m = reg.Match(content);            }            //this._FinalHtmlCode = content;    //bad  风格不好的使用方式..应该直接return 这个content                 return content;        }        /// <summary>        /// 生成最终的HTML代码        /// </summary>        public override void MakeHtmlCode()        {           this._FinalHtmlCode = ParseLabelConetent(this.LabelContent);        }


而私有化是为了减少程序员在用的时候不知道,调用这个类的那个方法...减少程序员猜测的时间... 一个类在设计的时候尽量做到做一件事情只需要一个方法,

如果一个对象只做一件事情,那么这个对象就应该只有一个方法public . 而不是把所有的方法都公开, 更不是把所有方法都公开后让其它程序员,一个一个的按照顺序调用...

例如:在设计一个人的跑步方法时就不应该.写成

class 人

{

public 抬左脚(),

public     抬右脚()

}


这样用起来会很麻烦... 用的人甚至要写for循环.才能让这个人跑起来...

.要遵循,面向对象的设计理念... 自己的事情自己做...不是自己的事情坚决不做..是自己的事情不要懒着做..(有的时候,也真是左右为难)

应该写成

class 人

{

public跑步(){

for()

{

抬右脚()

抬左脚()

}

}

       private     抬右脚()

        private     抬左脚(),

}

 


一个人会说话,会走路.. 这样的需求就应该有两个方法,  而不是一个方法 边说话边走路


class 人

{

public 说话(),

public     行走()

}


在c#中是属性就应该是属性,不要写成一个方法赋值,更不能一个方法中赋值多个属性..   


  

/// <summary>        /// 设置或获取模板路径        /// </summary>        public string TemplatePath         {            get { return Template._templatepath; }            set { Template._templatepath = value; }        }  /// 设置模块路径public void BackPath(string filename, string path)   //这样在别的程序员看了,这个方法用过后,哪个属性会改变呢?        {            _templatefilename = filename; //这样破坏了面相对象的设计原则,可以顺便赋值,但是不能专职赋值...              _templatepath = path;        }


java中则必须get和set.



先暂时写到这里吧..

原创粉丝点击