作者:陈勇

出处: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/JPAORM/archive/2011/04/29/2510509.html

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

  1. C#编码简单性之语义篇(如何编写简短的C#代码,随时更新)

    以前写C++的时候曾经在自己网站上发表过一个编码"简单性"之文章,现在编写C#了才发现自己无意之间就会写下一些浪费屏幕的代码. 下面是自己编码中偶然发现的一些案例,欢迎中等水平的编 ...

  2. C#编码简单性之泛型篇(如何编写简短的C#代码,随时更新)

    作者:陈勇 出处:blog.csdn.net/cheny_com 这是编码简单性系列中的其中一篇,之前几篇包括代码篇/函数篇/语义篇. 因为要积累案例,会随时更新. 之前提到:编码简单性的" ...

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

    以前写C++的时候曾经在自己网站上发表过一个编码"简单性"之文章,现在编写C#了才发现自己无意之间就会写下一些浪费屏幕的代码. 下面是自己编码中偶然发现的一些案例,欢迎中等水平的编 ...

  4. 第一篇:“大集中”应用系统的结构和技术特点3——复杂性和简单性于一体

    大集中应用系统是复杂的,无论从技术.应用规模.业务关系等哪一个方面来看,都是这样的. 首先,框架结构的复杂性.所有大集中应用系统在建设过程中都要基于基础框架来开发,其目的是为了屏蔽底层的技术细节.为了 ...

  5. 【叶子函数分享三十】SQL简繁转换函数

    --原帖地址:http://blog.csdn.net/htl258/archive/2010/04/20/5506045.aspx --全部的简繁对照 declare @jall nvarchar( ...

  6. PHP函数篇之掌握ord()与chr()函数应用

    ord()函数把字符转换为十进制数字,chr()函数把十进制数字转化为字符,在二进制,八进制,十进制与十六进制之间充当桥梁的作用 中文字符编码研究系列第三期,PHP函数篇掌握ord()与 chr()函 ...

  7. 架构师未来性的基础:简单性

    作者:高焕堂,misoo.tw@qq.com 首页:Back ee                                      e 架构师未来性的基础:简单性 Apple公司创始人乔布斯 ...

  8. Scala 函数篇笔记(二)

    文章目录 基础篇 函数和方法的关系 声明方式 参数个数 噩梦篇 至简原则 地狱篇(重要) 函数可以作为对象赋值给变量 函数可以作为参数传递给其他函数 练习: 小问题 函数作为返回值使用 闭包 Q&am ...

  9. R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型、分类预测器(分类变量)被自动替换为一组虚拟编码变量、summary函数查看检查模型、使用table函数计算混淆矩阵评估分类模型性能

    R语言使用R基础安装中的glm函数构建乳腺癌二分类预测逻辑回归模型(Logistic regression).分类预测器(分类变量)被自动替换为一组虚拟编码变量.summary函数查看检查模型.使用t ...

最新文章

  1. 报名 | 首期AI Time PhD:听清北师兄分享前沿研究成果!
  2. 服务端JavaScript之Rhino
  3. 使用crypto模块实现md5加密功能(解决中文加密前后端不一致的问题)
  4. C/C++中链接属性
  5. php和mvc的认识
  6. vi和vim命令行编辑器命令
  7. 关于Java的一些句子
  8. js 比较时分大小_JS 判断两个时间的大小(可自由选择精确度:天,小时,分钟,秒)...
  9. 吴恩达机器学习编程题ex1上 单变量线性回归: (python版含题目要求、代码、注解)
  10. 本週主題 -- Jakarta Commons Lang
  11. Android热修复升级探索——代码修复冷启动方案 1
  12. SQL Server 默认跟踪应用4 -- 检测日志文件自动增长
  13. dbeaver连接Oracle数据库
  14. velocity语法
  15. oracle 函数的使用
  16. 富士通陆宇澄:下半年推出主流价位超极本
  17. Android图片加载框架最全解析(五),Glide强大的图片变换功能
  18. 影子系统、还原精灵、冰点还原优缺点比较
  19. 小米运动蓝牙耳机重新配对_小米运动蓝牙耳机怎么连接手机
  20. 【Git下载安装与环境配置】

热门文章

  1. 05章项目: QuickHit快速击键
  2. 在Java中调用与系统有关的剪切板Clipboard
  3. 【matplotlib笔记】在图表中使用中文信息作为标签
  4. win10安装rqalpha开源回测框架
  5. 百倍加速!Python量化策略的算法性能提升指南
  6. php redis 封装类,php redis封装类
  7. 熬夜整理了免费的数据源网站大全,再也不愁找不到数据练手
  8. 让数据可视化告诉你,中秋吃这样的月饼绝对没错
  9. 数据分析方法(一):对比与对标
  10. python常用模块用法_python笔记之常用模块用法分析