辛巴学院-Unity-剑英陪你零基础学c#系列(四)函数和封装
辛巴学院:正大光明的不务正业。
国庆长假结束了,我的心情是这样的:
你总是起不早,起不早
独自一个人沉睡到天亮
你无怨无悔的梦着那副本
我知道你根本就不想上班
你总是起不早,起不早
放假总是短暂,上班太难
请个病假,再睡上一天
今天我们聊c#的函数和封装
这个话题其实你有无数的资料,每个写过代码,没写过代码的人,都知道这些玩意。
我也没有太多新奇的角度,先记住这一点
这不是数学,这不是数学,这不是数学。
我接触最早的语言是basic,那个时候函数还没有那么深入人心,不是visual basic,dos时代接触的。有一些系统函数可以调用,自己写小程序却鲜少定义函数,或许是不能定义,反正我学那会完全不知道。
讲basic干什么?这不是关于c#的文章么?只是告诉你,曾经存在不那么依赖函数和封装的语言,函数不是必须的。但c#,或者说c系语言,都是以函数和封装作为基础。那么你可能会思考,一个不用函数和封装的代码该怎么写?过去的basic 有行号,可以goto 到一行接着执行。我们就依靠这个goto,将代码划分为几块,跳来跳去。
这实质上就是一个没有语法保障的封装,实质上就是函数。在c系语言,你也可以用goto,实际上编译成机器语言以后,本来就是goto来goto去。
把一块功能组织在一起,就叫做封装。专门将一块功能标记为一段子程序的语法,这就是函数。
每一行代码都是你的宝贵财产,比如衣服,两三件的时候,随便放在那里就行了。几十件的时候,不分类整理一下就有点麻烦了。几百件的时候,可能还要先分房间再分衣架。
这种需求就是封装的需求,它是随着系统复杂度的提升,自然而然会出现的需求。
如果你一时还完全体会不到这种需求,那先不要去考虑研究函数,研究封装,先去用一个函数写完整个程序,一直如此,一直如此。如果最终你也无法感受到封装的需求,那你也可以成为一个独特的程序员。
C#的函数语法是这样的 【修饰符】类型 函数名(【参数1】,【参数2】,…){…}
这玩意说不说也都差不太多,大家都知道。
怎么设计函数?
最关键是你能体会那种看到一个500行的函数,有一种好想好想把他重新整理成好几个函数的强烈冲动么?
这种冲动是学习函数设计方法,也就是学习封装的关键所在。
你也许已经发现很多优秀的程序员,他们却说不出什么,他们明明能写出优秀的代码,却不能解释为何要如此写,应用了何种方法或原则。
这一类程序员就是【本能型】,他们学会了基本的语法之后,跟着那种整理的冲动,一步步走向优秀。我认为本能型是最轻松的一种类型,爱和悟性,正是你最大的助力。
然而,世事总不如人意,总有些人需要一点帮助才能找到自己的切入点。
所以我们还是来探讨一下,函数怎么封装?
从命名开始,再写调用,至于实现,再说吧。
所有好的函数设计都是从命名开始的,然后编写调用代码,至于实现,呵呵,爱谁写谁写,如果你没有助手,那就是你写。现在你可能对这个讲法有着深深的怀疑,没关系。我们先谈命名。
你可能听过几种命名法,比如著名的匈牙利命名法。我们聊的是命名法的使命。命名法的使命是让一个名字清晰,准确,易识别。就.这.么.简.单。
- 用英文。我不抵制拼音,我说的是用英文字母,别用中文或火星文,输入起来太烦心,26个英文字母不借助任何输入法可以用键盘敲出来,这是天然的优势。无论你是怎么样的一个热爱自己民族文化的人,我相信你也不愿意抵抗这个优势,你可以造一个5000个按键的键盘,每个键对应一个常用中文字,我十分怀疑你要花多久才能熟练使用这样的一个键盘。至于用拼音,那只是一个low的问题,只是让你看起来像是一个土拨鼠,话说回来,随便查字典得来的英文要慎重,别随便乱用,要查就查个彻底,搞清楚语境用法,否则也还是一只土拨鼠。
- 无论哪种命名法,他都由单词和分隔符两个部分构成,有两种世界通用分隔符,下划线和驼峰法。举例m_Gold DoSth别发明你自己的特别分隔方法。单词没关系,用简写一定要用约定俗成的,简写取几个字符是不能乱来的,你自己定的规矩,别人怎么可能懂,比如inte 你知道是个what? 用Integer 或者int。cha 你知道是个what?用character 或者 char。
- 函数名字是动宾短语,变量名字、类型名是定语修饰从句。好吧,先给语文老师上柱香,我也不确定我说的对不对。
Void 打() 这就不是个好命名,因为没宾语,根据上下文也推断不出来打谁。Void 打豆豆()就好些了
Void 转圈() 这就问题不大,可以很容易推断出是自己转圈。此处用中文只是为了说明,别挑我理哦。
Int 金币 int 豆豆的金币 根据上下文,他们都是语文,你要从语文的角度考虑话说清楚了没。命名,本来就是文字的事儿。
命名说完了。
让我们回到先写调用还是先写实现的问题上。这个问题有个有趣的现象,大部分新手程序员都认为应该先写实现,当他们成为老手之后,就统一认为应该先写调用。
我们来思考这样一个问题?程序没跑起来之前,程序员是否知道程序的运行顺序。答案是知道。
我们再来思考这样一个问题?一个不知道其细节实现的函数,程序员是否能使用,答案是能。
我们再来思考这样一个问题?我们观察程序结构是看什么,看到我们欲观察的结构的末端时?我们需要看其函数实现么?答案是不需要。
程序设计就是程序没跑以前先规划好他怎么跑,规划程序怎么跑就要设计程序的结构,就是设计谁调用谁,不知道实现细节的函数不影响我们设计程序
所以
永远先写调用,再写实现,是程序设计的铁则
我想说这就聊完了,不过还是要照顾一下悟性不高的同学。
还是不免俗的来几条函数设计原则:
函数不要太长,100行以上就值得再思考一下了,空行不算。
所有的设计原则基本上都是经验原则,100 80 200 你也可能会听到各种版本,没关系,都一样,都是个经验数字。这个原则的出发点是别写太长,不容易看懂
函数命名就已经决定了函数做什么事,聚焦在这件事上,无论参数、返回值实现都要忠于这件事,否则,去另一个函数。
在阅读时好的函数是不需要看其实现就能理解其作用的,一个与命名不符的函数就是一个坑,虽然每个程序都是在坑人与被坑之中成长的,但是提前记得这个原则,会给你提供一定的帮助。
函数的一致性,就是函数的输入一致,输出就应该一致。
函数别增加和他无关的状态,这一条理解起来比较困难,所以我们分开讲
随机数函数表面看起来每次的输入都是空,返回都不同,其实并不是如此,随机数函数有个隐形输入,随机种子。随机种子一样,随机数函数返回就一样。
所有的函数都是这样的,计算机中不存在不确定的状态,所有的状态都确定,只有像随机种子、时间这类代码阅读者不易察觉的隐形状态。
这一条就是说要慎重设计函数的隐形状态,保持其从外部易于观察。
比如你写了一个函数 addrandhp(10),然后其行为是加 5 到 15点血,在10 加正负5范围。这就有个隐藏状态正负5之间的随机。
Addrandhp(5,15)用这样的设计方式就从外部容易理解其行为。
函数应尽早报告错误,比如先检查下输入是否合法。
在执行中函数出错,应该给予正常的异常反馈,用throw xxx,这也是有争论的,有不同的方法论。但是微软的类库里都是尽量早抛出异常的,我们跟随微软的风格。
不知不觉可能把零基础系列做的比较复杂了,可能我就适合写这种装逼效果的文字,反省反省。
再会,哈库拉玛塔塔
辛巴学院-Unity-剑英陪你零基础学c#系列(四)函数和封装的更多相关文章
- 辛巴学院-Unity-剑英陪你零基础学c#系列(一)Hello World
这不是草稿 辛巴学院:正大光明的不务正业.辛巴学院:攻城狮与荣耀石. 剑英陪你系列又来啦.剑英是一个有大爱的人,热爱每一个程序员,尤其是年轻漂亮的女程序.最近组织朋友们玩了一次即兴团体诗创作,无论怎么 ...
- 辛巴学院-Unity-剑英陪你零基础学c#系列(三)计算与类型
辛巴学院:正大光明的不务正业. 中秋节快乐,每逢佳节倍思亲,尤其是那素未谋面的老婆,对吧,屌丝们. 今天我们来探索一下C#里面奇怪的计算,奇怪的类型. 奇怪的计算 当我刚刚接触计算机编程的时候,一 ...
- 辛巴学院-Unity-剑英陪你零基础学c#系列(二)顺序
这不是草稿 辛巴学院:正大光明的不务正业. 上一次的教程写出来之后,反馈还是挺多的,有很多都做了修改,也有一些让人崩溃,不得不说上几句.有些人有些很奇怪的地方,你写篇东西,被看了以后不说他感觉怎么 ...
- 辛巴学院-Unity-剑英的c#提高篇(一)主循环
这是测试版 辛巴学院:正大光明的不务正业. 最近刚刚离开了我服务了三年多的公司,因为一个无数次碰到的老问题,没钱了. 之前不知道做什么好的时候,机缘巧合之下和哒嗒网络的吴总聊了一下,发现了vr gam ...
- 剑英陪你玩转图形学(五)focus
很久没来和大家交流业务(zhuangbi)水平了,最近实在是很忙,报名了小游戏大赛,一点时间都抽不出,已经坑了. 今天抓紧时间和大家介绍一个小效果: 新手引导的时候,我们会需要一种全屏幕黑掉,只有一个 ...
- (转载)李剑英的CSLight入门指南结合NGUI热更新
原地址:http://www.xuanyusong.com/archives/3075 李剑英的CSLight入门指南文档撰写者:GraphicQQ: 1065147807 一. CSLIGHT 作者 ...
- 辛巴达:帮电商打造ZARA式开放供应链体系 - 行业网站 - 亿邦动力网
辛巴达:帮电商打造ZARA式开放供应链体系 - 行业网站 - 亿邦动力网 辛巴达:帮电商打造ZARA式开放供应链体系
- [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之纹理Textures
[我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之纹理Textures 本篇分享一下第6个已完工的视频,即<beginner Graphics ...
- [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之网格Meshes
[我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之网格Meshes 本篇分享一下第5个已完工的视频,即<beginner Graphics – ...
随机推荐
- 再谈缓存和Redis
自从上次分享<Redis到底该如何利用?>已经有1年多了,这1年经历了不少.从码了我们网站的第一行开始到现在,我们的缓存模块也不断在升级,这之中确实略有心得,最近也有朋友探讨缓存,觉得可以 ...
- "Fatal error: Call to undefined function: file_put_contents()"
打开页面时提示这个错误: Fatal error: Call to undefined function: file_put_contents() 意思是请求未定义的函数,出现这个提示通常有两种情况: ...
- 远程debug调试java代码
远程debug调试java代码 日常环境和预发环境遇到问题时,可以用远程调试的方法本地打断点,在本地调试.生产环境由于网络隔离和系统稳定性考虑,不能进行远程代码调试. 整体过程是通过修改远程服务JAV ...
- Winform窗体最大化的时候,如何指定窗体的位置、大小
一.重写窗体的SizeChanged事件不能改变窗体最大化的位置和大小. public partial class Form2 : Form { public Form2() { Initialize ...
- UWP学习记录12-应用到应用的通信
UWP学习记录12-应用到应用的通信 1.应用间通信 “共享”合约是用户可以在应用之间快速交换数据的一种方式. 例如,用户可能希望使用社交网络应用与其好友共享网页,或者将链接保存在笔记应用中以供日后参 ...
- 初识node.js
Node.js不是一种语言:不是框架:也不是工具.它是用于运行基于JavaScript应用程序的运行时环境.
- Android 延时执行任务的三种简单方法
开启一个新的线程 new Thread() { @Override public void run() { try { Thread.sleep(2000); } catch (Interrupted ...
- (转)Lock和synchronized比较详解
今天看了并发实践这本书的ReentantLock这章,感觉对ReentantLock还是不够熟悉,有许多疑问,所有在网上找了很多文章看了一下,总体说的不够详细,重点和焦点问题没有谈到,但这篇文章相当不 ...
- python学习4 常用内置模块
logging os 路径处理 // 获取当前路径 os.path.abspath(__file__) //获取当前文件夹路径 os.path.dirname(os.path.abspath(__fi ...
- Asp.Net WebApi开发注意
1.Api的版本控制 2.Api的异常处理 设置全局异常处理 3.Api的权限控制 4.Api的请求处理 get:查询 post:创建 put:修改 delete:删除 5.Api的文档说明