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

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

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

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

下面是易读, 易修改 的代码: 缺点是不好用,需要学习很多知识才能上手.达不到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.



先暂时写到这里吧..

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值