公共操作类开发技巧(初学者必读)

本文专门为初学者而写,因为很多初学者可能还不了解公共操作类的作用和封装技巧,大部分有经验的程序员都会把自己所碰到的技术问题整理封装成类,这就是公共操作类。公共操作类往往具有一些通用性,也可能专门解决某些棘手问题。公共操作类是应用程序框架的核心,主要目标是解决大部分技术问题。我将在本文介绍封装公共操作类的要点,供初学者参考。

开发公共操作类的原因

很多初学者会奇怪,.Net Framework提供的API相当易用,为何还要多此一举,进行一层封装呢。下面列举封装公共操作类的一些动机。

.Net Framework API太过庞大

想想看.Net Framework包含多少个程序集?每个程序集包含多少个命名空间?每个命名空间包含多少个类?每个类包含多少个属性和方法?在如此庞大的代码海洋中游泳,你没有一艘船怎么能行。

现在给你一个任务,需要实现一个文件上传功能,但你从来没有做过,你会怎么办?由于你不清楚.Net哪个程序集包含这个功能,更不知道使用哪几个类的方法组合可以完成这个任务,所以必须查资料,很少有人能直接在VS上自己把它摸索出来。

你会进行以下步骤:

  1. 百度(为啥不用Google,打不开啊,你不会因为一个简单问题就FQ吧,不过很多生僻和棘手的问题,百度和国产搜索引擎都靠不住,只有Google才能给你指出方向)

  2. 进入搜索出来的前几篇文章,找到需要的代码。

  3. 复制到项目中调试。万一你运气好,一下就通过了,这时候就可以收工,运气不好继续百度。

可以看出,当你碰到一个没做过的功能一定需要查资料,因为.Net类库太大了,你不可能先把所有的东西学会再进行开发。观察以上步骤,可以发现你的开发速度和找到正确代码的时间成正比。换句话说,如果你找东西的时候,关键词没有输入正确,或者东西本身很生僻,你就会拿出大把的时间持续在网上冲浪。

获得更好的代码提示支持,帮助记忆API

.Net开发门槛很低,其中一个重要原因是VS非常强大,特别是代码提示功能。

如果现在叫你用记事本来开发一个模块,结果会怎样?除了开发效率低得吓人,恐怕写出来的代码编译都难通过,关键一点是你无法精确的记住API。很少有人能精确的记住他使用的每个命名空间,类名,方法名等,大部分人都只有一个印象,可能记得住命名空间和类名的一部分,依赖VS强大的代码提示功能,上下移动以定位正确的API。

这是一个非常强大的特性,但是由于.Net Framework类库过于庞大,以及第三方框架的API也非常复杂,从而削弱了代码提示的能力,细长的代码提示滚动条让你眼花缭乱。

另一方面,我们平时使用的API数量非常有限,只占总数1%不到,把这些常用的API封装到自己的命名空间中 ,可以大大加强代码提示能力,从而帮助你记忆API, 凭借一点模糊的记忆,根据代码提示进行开发。

获得更好的代码复用能力

现在来看代码的复用性。

过了三五个月,已经是下一个项目开始了,你又需要进行文件上传。这时候,你会意识到之前做过这个功能,但记忆已经很模糊了。记忆很模糊的原因除了时间比较长了以外,还有个原因是你当时直接从网上复制过来,根本没有理解。你现在一个选择是再次百度,但很多时候你不愿意这样干,可能是上次找东西不大顺利,花了大半个小时才找到。也可能是你上次找东西的时候挨了病毒,现在心里还有阴影。另一个原因是你觉得之前的代码一直在使用,比较稳定,所以你决定去老项目里面把这段代码揪出来。然后你打开已经混乱不堪的项目,四处东翻西找,终于找到,把它复制过来。

可以看到,没有经过封装,就只能复制代码。这个过程费力,耗时,完全没有必要。

有经验的程序员,虽然也要搜索代码,但会多几个步骤,从网上找到的代码就算能用,也还要进行整理、封装以及单元测试。完成代码封装以后,就可以直接调用,不再东张西望。

获得更好的可维护性

将常用代码封装后,所有代码调用点都指向同一个地方,如果发现BUG或者新增功能,只需要修改一个地方。

简化API调用

有些代码确实很常用,记得很牢,但是太啰嗦,可以封装之后创建一套更简易的API,以方便调用。

更好的管理第三方API

对第三方API进行集中管理,特别是方便切换。

公共操作类开发技巧

技巧一:尽量使用静态方法

公共操作类应该尽量使用静态方法,因为这样调用起来比较简单,谁也不希望为了一个很简单的操作,还要先实例化对象。

不过如果你需要考虑切换实现,或者需要多次调用,就不应该使用静态方法。

技巧二:封装啰嗦代码,一行搞定

能一行代码写完,谁愿意写两行?有些操作虽然简单,但需要写好几句,这时候你要考虑封装起来,调用时仅一行搞定,从而简化API。

技巧三:粗粒度

你不能按.Net Framework那样细的粒度来封装常用类,因为这些很快会导致大量的类,从而让你无法迅速想到你需要的功能在哪个类中。同时也会显著削弱代码提示的能力。

公共操作类是.Net Framework和第三方框架上方的一层外观,提供一个粗粒度的视角让你调用API更简单。

技巧四:把记不住的都封装起来

如果你的记忆力非常糟糕,很多常用的都记不清楚,没有关系,封装到你的公共操作类中,它会帮助你记忆,因为你以后只需要在代码提示上移动了。

技巧五:形成清晰的API

你必须为你要封装的功能取一个语义清晰的类名,以及方法名。如果你为了图快,胡乱取一个,那么下一次你可能在杂乱无章的公共操作类中迷失方向,因为你不知道哪个类和方法完成你要的功能。

公共操作类,一般会被冠以Helper后缀,比如ConvertHelper,但这不是必须的,我发现用更短的名称会让调用时更爽。我后面使用Convert,不过这与系统类名冲突,虽然在不同的命名空间中,Resharpe会提示多个命名空间,这让我很不爽,所以我将Convert又缩短了一点,叫Conv。一般来讲,除非没有其它选择,否则命名尽量不要使用缩写,这样会导致很晦涩的API。我在公共操作类中使用一些缩写,是因为我非常熟悉,并且其它人也比较容易理解,另外也确实是走投无路,不想使用长名称。

把可能发生变化的部分抽取出来,作为参数传进去。

技巧六:仅要求必须的参数

为了让调用代码更简单,把不是必须传递的参数尽量隐藏到公共类中,或提供参数默认值,这也是封装的关键。有时候哪怕减少一个参数,都会让工作量减轻很多,因为这个方法可能被大量的调用。

技巧七:提供适量的方法重载

为了让某些功能用起来更灵活,需要提供方法重载。应该针对最常用的几个操作提供重载,提供太多重载会导致复杂性。

技巧八:添加准确而清晰的注释

公共操作类高度依赖代码提示功能,所以准确而清晰的注释,就显得很有必要了。

你虽然尽了最大努力来设计清晰的类名和方法签名,但别人不一定理解,另外时间长了你自己都会犯傻。这里有一个重要原因是我们老中英文好的毕竟是少数,大部分人还是和我一样爱国,英文烂得一塌糊涂,所以哪怕很用心的设计API,还是个四不像。依靠准确的注释来弥补这个不足是非常有用的。

对于复杂的功能,在注释上直接提供范例,可以让你在调用时更轻松。

技巧九:抽取第三方API接口,以实现切换

为了不被第三方框架捆绑,需要在第三方框架上方建立一层封装。

一般做法是根据你的需求,抽取一个或多个接口,用第三方API实现这些接口。项目中只使用自己的API,第三方框架的API就不会侵入系统,这样就可以在必要时切换到另一个三方框架。

不是所有的第三方API都需要封装,如果它不侵入你的系统,就没有太大封装的必要,比如依赖注入框架。还有些框架不是很容易封装,你可能要使用它的大量API,另外它的API包含大量像Lambda这样的东西,你封装起来就很痛苦了,如果这种框架稳定性比较高,一般不轻易更换,直接调用也没有多大问题。

公共操作类开发注意事项

警惕过度封装

当你逐步习惯了自己封装API以后,你可能会把系统大量的API封装进来,从而导致过度封装。

怎样才算过度封装?这其实是一个主观判断,我可能觉得你过度封装了,但你自己却认为相当好用,这是因为我两的习惯和风格不同所致。对于这点,不用理会其它人怎么看,只要你自己用得爽就对了,当然你如果带团队,你的团队成员如果用起很痛苦,你可能就得改改了。

如果你自己都发现框架越来越笨重,每次在代码提示上下移动要花很长时间,这就是一个信号,把用不上的统统干掉,你的框架也需要经常洗洗澡。

不要忽视简单功能

并不一定是技术比较困难的才需要封装,其实简单的也需要。这一点,哪怕很多老手都会忽视。

要把简单的东西封装起来不是一件易事,因为你可能把简单的东西搞复杂了,换句话说,犯了过度封装的毛病。但你如果仔细观察,会发现还是有很多简单的功能可以更简化。

我会在后面发布一些有用的公共操作类实例进行详细说明。

结语

本篇详细的介绍了公共操作类的基本技巧,当你以后碰到任何一个技术问题时,应该首先想到的就是封装成公共操作类,以供日后复用。

对第三方硬件设备接口和应用平台接口的封装,也可以归纳到公共操作类中,只是属于业务范畴。

本系列是介绍应用程序框架整体的,而公共操作类只是其中一个组成部分,虽然它占据了大半江山。为了不喧宾夺主,把应用程序框架整体冲淡,我准备单独开一个系列来专门介绍公共操作类,命名为《Util应用程序框架公共操作类》,到时我会把一些常用的公共操作类奉献给大家。

应用程序框架实战