C#编码简单性之函数篇(如何编写简短的C#代码,随时更新)

作者:陈勇

出处:blog.csdn.net/cheny_com

 

这是编码简单性系列中的其中一篇,之前几篇包括代码篇和语义篇。

因为要积累案例,会随时更新。

 

之前提到:编码简单性的“心法”就是:只要屏幕上有任何两部分代码看上去相似,则一定有合并办法。
但在代码层面,无论如何简化,都常常剩下一堆相似代码,这时候就需要编写函数了。

这里指的函数,包括HtmlHelper这类用C#解决Html的函数。

 

应随时关注代码中的“不简洁”现象,一旦放任其发生,软件将很难维护。


案例1 从Html代码抽取MVC HtmlHelper

为了在屏幕上显示一些大按钮(下方显示其文字),编写了这些代码。为了对齐/消除边框/Hover效果等,动用了几个class来设置格式。按钮很多,所以需要相当数量的拷贝粘贴,其中文字-alt-title还是重复的,每次都要改动三个地方……

这些,都是代码正在变复杂的坏味道。

 

以其中两次重复为例,说明修改方法:

            <td class = "noborder nopaddingv">
                <div class = "aligncenter">
                    <a href="/Home/Index">
                        <img src="../../Resouces/Images/Agile/Menu/Campass48.png" alt = "站点地图" title = "站点地图" class = "imagelink"/></a><br />
                        站点地图
                </div>
            </td>
            <td class = "noborder nopaddingv">
                <div class = "aligncenter">
                    <a href="/Home/Index" target = "_blank">
                        <img src="../../Resouces/Images/Agile/Help/Help48.png" alt = "帮助" title = "帮助" class = "imagelink"/></a><br />
                        帮助
                </div>
            </td>

手段就是做HtmlHelper(以前没做过复杂的,所以推到现在才做),结果是:

 

        @Html.MenuImageButtonV("站点地图", false, "/Home/Index", "../../Resouces/Images/Agile/Menu/Campass48.png")
        @Html.MenuImageButtonV("帮助", true, "/Home/Index", "../../Resouces/Images/Agile/Help/Help48.png")

Helper的内容就不展示了,网上一查都会。唯一说明的就是class变成了style,因为在函数内部引用class是危险的,不能保证被复用后class也在。

突然想起来当年曾经写过一句话很好地概括了这种技法:当两段代码相同时,可以变成一个函数和两次调用,相同的部分就是函数,不同的部分就是调用参数。

可以看到本例中,只有文字(title/alt)、是否新窗口打开、链接、图片不同,所以就是一个有四个参数的函数。

 


案例2 2011-05-04 函数接口的简洁性 

不是编写了函数就万事大吉了,不好的函数接口依然不简洁。下面是一个刚改好的例子:

@Html.ImageLink("燃烧图", true, "../../Resouces/Images/Agile/CurrentSprint/BurndownData16.png", "icons", false, "/Agile/CurrentSprint/BurndownData", null, null)

@Html.ImageLink("迭代计划", true, "../../Resouces/Images/Agile/Sprints/Index16.png", "icons", false, "/Agile/Sprints/Index", null, null)

...

像这样的函数重复上几回也很让人头痛的,关键臭长的函数还看不到尾部,很容易出错或影响阅读。

这时候的技法是:如果函数在重复调用时有些参数变化,有些参数基本不变("icons", true, false, null....),后者应该变成一些可选参数并设置缺省值。

修改后的结果(另外一段代码):

@Html.ImageLink("迭代计划", "/Agile/Sprints/Index", true) //这个true有些地方不太一样所以留下了。
@Html.ImageLink("迭代故事", "/Agile/Sprints/SprintStories", true)

...
唯一的不太好理解的是图片的链接哪去了。我在后台目录做了一套命名规则,若imgPath为缺省值null,则会根据命名规则生成默认图片名称,保证图片可以用Area/Controller/Actoin定位。这样也简化了实现和维护,不用去在脑海里便维护一套图片与链接的对应关系,也是编码简单性的一种体现。


案例3 2011-05-04 MS Chart Winform版本与MVC3 Razor Helper的比较

在Winform版本中,一个Chart除了要在aspx中放置控件外,还要这样设置参数:

Chart1.Series["Series1"].ChartType = (SeriesChartType) Enum.Parse( typeof(SeriesChartType);

Chart1.Series["Series2"].ChartType = (SeriesChartType) Enum.Parse( typeof(SeriesChartType); ChartTypeList.SelectedItem.Text, true );

Chart1.Series["Series1"].IsValueShownAsLabel = true;
Chart1.Series["Series2"].IsValueShownAsLabel = true;
Chart1.Series["Series1"]["LabelStyle"] = PointLabelsList.SelectedItem.Text;
Chart1.Series["Series2"]["LabelStyle"] = PointLabelsList.SelectedItem.Text;
...

这是非常难读的代码,至少相当的不直观,MVC3的程序员显然要厉害得多(应该是MS意识最好的程序员了,要不做好不MVC),他们的代码长得这个样子:

new Chart(400, 200, ChartTheme.Blue)
.AddTitle(title)
.DataBindTable(data, "X")
.Write("png");
看来是由于工作量问题,beta版本实际上只实现了很有限的几个函数,但实现得却很漂亮。按照这种风格写上面那个Chart1,应该是(仅展示风格):

new Chart()

    .AddSeries( new Series("Series1",

        ChartType: (SeriesChartType) Enum.Parse( typeof(SeriesChartType)),

        IsValueShownAsLabel: true)

        .AddLable( new Label(

            LableStyle:PointLabelsList.SelectedItem.Text)

    ....

这种风格很类似JQuery中的风格,是一种“写得少,做得多”的风格,其心法就是:代码里边没有任何两个地方看上去相似。


案例4 2011-05-05 函数接口不简洁的深层原因

01年左右曾经有一家国内排名前3的家电厂商做了一款机顶盒在我们公司联合测试。此机顶盒稳定性很差,其程序员长驻现场有问题就改,而问题也从不停息,比同期测试的其他几家机顶盒差很多。一年后有一个偶然的机会被请去评价一段机顶盒代码是否可用,从函数名称等蛛丝马迹判断就是这个厂家的代码,答案是:不可用。

那些代码外观的第一感觉是像一篇小说,每行都很长,能自成段落的都有,有点像案例3中开始不好的代码且更甚之,最后对代码进行了局部改造,量化评价的结果是实际所需代码大概是已有代码的1/6。

怎么才能变成案例3里边后面那种长得像诗词而不是小说的代码呢?

当时我们分析那段机顶盒代码,问题出在类的封装上,总结一下包括:

1. 类的内聚性不好,多数函数属于哪个类都不好,因为哪个类的变量都不足以支撑计算,只得在单独声明一个函数(当时是用C++,C#不允许了),传入大量类。

2. 类的封装不好,多数类都使用public的内部数据,很容易出现Chart1.Series["Series2"]["LabelStyle"] = ...这种从chart挖到Series,从Series挖到LableStyle才能干活的情况,所以函数调用臭长。

再深入挖掘一下形成这种结果的原因,在于多数程序员(本人也一样)都喜欢先从类的变量而非类的函数开始设计,最终导致类更适合存放数据而不适合做事。一种解决办法就是所谓调用驱动开发,就是先把要调用的代码写出来,打桩,再实现

 

点击下载免费的敏捷开发教材:《火星人敏捷开发手册》

 

转载于:https://www.cnblogs.com/spring3/archive/2011/04/29/2401485.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/378465.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

R学习笔记(1):R是什么

本文最新版已更新至http://thinkinside.tk/2013/05/03/r_notes_1_what.html 在学习量化投资的时候&#xff0c;我发现了R&#xff08;www.r-project.org&#xff09;。R到底是什么呢&#xff1f;在开始之前&#xff0c;先看看R的神奇之处。 1. R初窥 从CRAN&#xff08;The Co…

数字图像处理知识总结

一&#xff1a;基本概念 数字图像&#xff1a;指由被称作像素的小块区域组成的二维矩阵。将物理图像行列划分后&#xff0c;每个小块区域称为像素&#xff08;pixel&#xff09;。每个像素包括两个属性&#xff1a;位置和灰度。图像数字化一般分为采样、量化与编码三个步骤。数…

oracle marley,滚石杂志500大专辑,对欧美音乐感兴趣的可以找来听听。

滚石杂志于2003年11月评选出的滚石杂志五百大专辑。值得一提的是&#xff0c;披头士乐队占据了前五中的三席&#xff0c;前五十中的7席&#xff0c;正式出版的专辑几乎全部入选前五百。排名 演唱者 专辑001 披头士乐队(The Beatles) Sgt. Peppers Lonely Hearts Club Band002 海…

kinect中psi是什么_PSI的完整形式是什么?

kinect中psi是什么PSI&#xff1a;每平方英寸磅/国际人口服务 (PSI: Pound per Square Inch / Population Services International) 1)PSI&#xff1a;每平方英寸磅 (1) PSI: Pound per Square Inch) PSI is an abbreviation of Pound per Square Inch. Pound per Square Inch …

jupyter notebook指定工作目录

【1】打开Anaconda Navigator 打开Anaconda Navigator&#xff0c;点击左侧Environments&#xff0c;点击base(root)->open Terminal 【2】输入指令jupyter notebook --generate-config 按下回车键&#xff0c;弹出config所在位置。 以VS Code打开文件 【3】修改第26…

五、“嵌段共聚醚酯型”易去污整理剂的结构特点及对织物服用性的影响?

“嵌段共聚醚酯型”易去污整理剂的结构特点及对织物服用性的影响? 收集资料阶段 嵌段共聚醚酯型易去污整理剂(简称聚醚酯)是涤纶最早的一种耐久性易去污剂,其商品名称为Permalose T,由英国ICI公司生产,它能使涤纶及其混纺织物具有优良的易去污、抗湿再沾污和抗静电性能。…

linux服务器指示灯,【转】明明白白你的Linux服务器——故障篇 | 旺旺知识库

在Linux/unix服务器的维护过程中&#xff0c;遇到各种各样的问题&#xff1b;有的严重&#xff0c;有的很好解决&#xff0c;有的解决过程我就记录下来与大家分享下&#xff0c;希望能给大家带来帮助。故障一、今天早上来的第一件事&#xff0c;就是检查昨天晚上刚刚重新安装的…

构件图(Component Diagram)—UML图(八)

构件图是显示代码自身结构的实现级别的图表。构件图由诸如源代码文件、二进制代码文件、可执行文件或动态链接库 (DLL) 这样的构件构成&#xff0c;并通过依赖关系相连接 下面这张图介绍了构件图的基本内容&#xff1a; 下面这张图是个构件图的实例&#xff1a; 转载于:https:/…

GAE work

https://appengine.google.com/ can visit in Home, but cannot visit in Office.Download a java SDK for GAE, will write something here.转载于:https://www.cnblogs.com/cnyao/archive/2011/05/05/2038161.html

二进制文件签名_二进制数的签名表示

二进制文件签名Prerequisite: Number systems 先决条件&#xff1a; 数字系统 Until now, we have only talked about positive numbers and have already discussed their mathematical operations. But there also exists negative numbers in the number system, in this a…

六、解释红外线纺织品的保健、保暖作用?

解释红外线纺织品的保健、保暖作用&#xff1f; 收集资料阶段 人体既是远红外的辐射源又能吸收远红外辐射。由于人体60&#xff05;&#xff5e;70&#xff05;为水‚故人体对红外辐射吸收近似于水&#xff0c;人体组织所拥有的特定振动频率和回转周波数与人体组织中的O&…

linux yum命令作用,YUM命令使用示例

YUM或Yellowdog Updater Modified是管理rpm包的前端工具。 它用于通过命令行界面或使用图形模式来安装&#xff0c;删除&#xff0c;更新和收集有关rpm软件包的信息。 使用YUM的主要优点是&#xff0c;它解决了rpm包的所有依赖关系&#xff0c;并将它们与包一起安装。下面让我们…

PySide开发MySql远程备份工具

MySql数据库安装在机房&#xff0c;而工作人员日常办公的地方距离机房有段距离&#xff0c;且不在同一楼层。出入机房不是很方便。就想着能否给这些人员开发一个图形化的备份MySql数据库的小工具&#xff1f;使用组件如下&#xff1a;(1)Python(2)PySide(3)mysqldump其实mysql已…

HadoopSourceAnalyse --- Nodemanager Container request handler

Overview Container 是Hadoop中运行任务的地方&#xff0c;当Resourcemanager收到一任务请求后&#xff0c;会向nodemanager 请求一个Container 来运行ApplicationMaster&#xff0c; ApplicationMaster运行起来之后&#xff0c;会继续向Resourcemanager请求新的container来运行…

数据结构 二叉树的存储结构_线程二叉树| 数据结构

数据结构 二叉树的存储结构线程二叉树 (Threaded Binary Tree ) A binary tree can be represented by using array representation or linked list representation. When a binary tree is represented using linked list representation. If any node is not having a child …

八、关于防水透湿整理

1,防水透湿整理加工技术的类型? 收集资料阶段 按照加工方式分类 防水透湿织物按照加工方式可分为高密织物、涂层织物和层压织物。不同加工方式所对应的织物各有特色。高密织物产生于 20 世纪 80 年代,它的密度可达到普通织物的 20 倍。在晴朗天气时,纱线孔隙大约为 10 μm…

求质数算法的N种境界 (N 10) zz

★引子 前天&#xff0c;俺在《俺的招聘经验[4]&#xff1a;通过笔试答题能看出啥&#xff1f;》一文&#xff0c;以"求质数"作为例子&#xff0c;介绍了一些考察应聘者的经验。由于本文没有政治敏感内容&#xff0c;顺便就转贴到俺在CSDN的镜像博客。   昨天&…

Python匿名函数---排序

一、列表的排序 nums [1,2,3,5,4,7,87,4,9,56,44,7,5] nums.sort()#默认从小到大排序 nums#结果为&#xff1a;[1, 2, 3, 4, 4, 5, 5, 7, 7, 9, 44, 56, 87]nums [1,2,3,5,4,7,87,4,9,56,44,7,5] nums.sort(reverseTrue)#从大到小排序 nums#结果为&#xff1a;[87, 56, 44, …

linux下怎么查kill某个进程,Linux下查询进程PS或者杀死进程kill的小技巧

假设我们要kill掉tomcat&#xff1a;那么我们首先需要tomcat的进程号pid&#xff1a;ps -aux | grep tomcat记下tomcat的PID后&#xff0c;执行&#xff1a;kill PID(tomcat)好了&#xff0c;就到这里....路人甲&#xff1a;小的们&#xff0c;灭了这个欺骗人民情感的家伙&…

opencv模板匹配

matchTemplate函数参数 模板匹配是通过模板在采集到的原图像进行滑动寻找与模板图像相似的目标。模板匹配不是基于直方图的方式&#xff0c;而是基于图像的灰度匹配。 6种匹配度量方法&#xff1a; 平方差匹配法CV_TM_SQDIFF 归一化平方差匹配法CV_TM_SQDIFF_NORMED 相关匹配…