这个如何写出优雅的代码代码

新手求教这个代码怎么写?【vb吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:103,448贴子:
新手求教这个代码怎么写?收藏
判题就是判断你做出的答案的对错
vb 编程培训选择达内的理由1,企业级开发环境2,项目实战教学3,net课程可选4,金牌讲师授课5,周末/业余班任选.vb 编程培训首选达内--美国上市公司!
求大神帮下判题这个按钮的代码怎么写?出题按钮我写的代码是:Private Sub Command1_Click()num1 = Int(9 * Rnd)num2 = Int(9 * Rnd)Text1.Text = Trim(Str(num1)) + op + Trim(Str(num2))Text2.Text = Trim(Str(num1)) + op + Trim(Str(num2))Select Case opCase "+": result = num1 + num2End Select
判题我写的代码是:Private Sub Command2_Click()If Val(Text3.Text) = result ThenIf Val(Text1.Text) + (Text1.Text) = result ThenMsgBox "恭喜你,答对了!"ElseMsgBox "答案错误!"End IfEnd IfEnd Sub
If Val(Text1.Text) + (Text1.Text) = result Then ??????
Private Sub Command1_Click()RandomizeText1 = Int((9 * Rnd) + 1)Text2 = Int((9 * Rnd) + 1)End SubPrivate Sub Command2_Click()If Text3 = Val(Text1) + Text2 ThenMsgBox "正确"ElseMsgBox "错误"End IfCall Command1_ClickEnd Sub
我来试下度娘吞帖没的,
急求,为什么文件里面的数组值不能传递给第一个过程Private Sub aver_Click()list1.AddItem &姓名& & Space(6) & &数学& & Space(3) & &计算机& & Space(3) & &英语& & Space(3) & &平均成绩&Dim n As Integer, aver() As Singlelist1.ClearFor i = 1 To nlist1.AddItem name(i) & Space(6) & math(i) & Space(6) & computer(i) & Space(6) & english(i) & Space(6) & aver(i)NextEnd SubPrivate Sub dataclear_Click()list1.ClearEnd SubPrivate Sub datain_Click()Dim name() As String, math() As Integer, computer() As Integer, english() As Integer, n As Integer, aver() As Singlelist1.AddItem &姓名& & Space(6) & &数学& & Space(3) & &计算机& & Space(3) & &英语&cdl1.Filter = &text (*.txt)|*.txt&cdl1.InitDir = &c:\&cdl1.ShowOpenfileno = FreeFileOpen cdl1.FileName For Input As #filenon = 1Do While Not EOF(fileno)ReDim Preserve name(n), math(n), computer(n), english(n)Input #fileno, name(n), math(n), computer(n), english(n)ReDim Preserve aver(n)aver(n) = (math(n) + computer(n) + english(n)) / 3list1.AddItem name(n) & Space(6) & math(n) & Space(6) & computer(n) & Space(6) & english(n)n = n + 1LoopFor i = 1 To n - 1aver(i) = (math(i) + computer(i) + english(i)) / 3NextClose #filenoEnd Sub
利用随机函数产生十个1~100之间的随机数 显示最大值 最小值 平均值
代码怎么写啊
什么代码代表什么程序啊,求求大神教教我。QQ
'添加 Command1 Command2 Label1 Text1 放进去就好啦,我会替你排列控件Dim aa%, bb%, cc$, dd%, TmpVal%, ExamNum%, CorNum%Private Sub Form_Load()
Label1.Width = 820
Label1.Move (Me.ScaleWidth - Label1.Width - Text1.Width - 100) \ 2, (Me.ScaleHeight - Text1.Height) \ 2
Text1.Move Label1.Left + Label1.Width + 100, Label1.Top - 100
Command1.Move (Me.ScaleWidth - Command1.Width - Command2.Width - 100) \ 2, Me.ScaleHeight - Command1.Height
Command2.Move Command1.Left + Command1.Width + 100, Command1.Top
Text1.Text = &&
Label1.Caption = &&
Command1.Caption = &出 题&
Command2.Caption = &刷 新&
ExamNum = 0: CorNum = 0
Me.AutoRedraw = True
Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
Me.Caption = &CBM666 的随机两位数加减法&End SubPrivate Sub Command1_Click()
Label1.Caption = &&
Text1.Text = &&
aa = Int(Rnd * 90) + 10
bb = Int(Rnd * 90) + 10
cc = IIf(Int(Rnd * 2) = 0, &+&, &-&)
If cc = &+& Then
dd = aa + bb
If bb & aa Then
TmpVal = aa
bb = TmpVal
dd = aa - bb
Label1.Caption = Trim(Str(aa)) & & & & cc & & & & Trim(Str(bb)) & & = &
Text1.Text = &&
Text1.SetFocusEnd SubPrivate Sub Command2_Click()
ExamNum = 0: CorNum = 0
Label1.Caption = &&
Text1.Text = &&
Me.ClsEnd SubPrivate Sub Text1_KeyPress(KeyAscii As Integer)
If KeyAscii = 13 Then
If Label1.Caption && && Then
ExamNum = ExamNum + 1
If Val(Text1.Text) = dd Then
MsgBox &正 确&
CorNum = CorNum + 1
MsgBox &答错啦&
Me.Print &第& & Str(ExamNum) & & 题 正确百分比:& & Format(Str(CorNum / ExamNum) * 100, &0.00&) & & %&
Command1_Click
KeyAscii = 0
End IfEnd Sub
通用管理软件不合适,定做管理软件太昂贵,自己开发太难,何不试试vb编程工具FoxTable?
一脸懵逼的路过
登录百度帐号推荐应用如何编写出更好的C#代码_西西软件资讯
西西软件园多重安全检测下载网站、值得信赖的软件下载站!
→ 如何编写出更好的C#代码
类型:编程辅助大小:410KB语言:中文 评分:5.7
开发人员总是喜欢就规范进行争论,但更重要的是如何能够在项目中自始至终地遵循编码规范,以保证项目代码的一致性。并且团队中的所有人都需要明确编码规范所起到的作用。在这篇文章中,我会介绍一些在我多年的从业过程中所学习和总结的一些较好的实践。举例为先我们先来看一个 FizzBuzz 示例。FizzBuzz 要求编写一个程序,遍历从 1 到 100 的数字。其中如果某数字是 3 的倍数,则程序输出 “Fizz”。如果某数字是 5 的倍数,则输出 “Buzz”。如果某数字即是 3 的倍数也是 5 的倍数,则输出 “FizzBuzz”。如果数字既不是 3 的倍数也不是 5 的倍数,则只需输出该数字本身。示例1: 1
public static void Test()
for (int i = 1; i & 101; i++)
if (i % 3 == 0 && i % 5 == 0)
Console.WriteLine(&FizzBuzz&);
else if (i % 3 == 0)
Console.WriteLine(&Fizz&);
else if (i % 5 == 0)
Console.WriteLine(&Buzz&);
Console.WriteLine(i);
}什么感觉?这段代码需要改进吗?示例2: 1
public static void Check()
for (int i = 1; i &= 100; i++)
string output = &&;
if (i % 3 == 0) { output = &Fizz&; }
if (i % 5 == 0) { output = output + &Buzz&; }
if (output == &&) { output = i.ToString(); }
Console.WriteLine(output);
} 现在感觉如何?还能不能进一步改进?好,让我们来尝试改进下。代码命名对所有软件开发人员来说都是件非常困难的事情。我们花费了大量的时间来做这件事,而且有太多的需要被命名的元素,例如属性、方法、类、文件、项目等。不过我们的确需要花费一些精力在这些命名上,以使代码中的名称更有意义,进而可以提高代码的可读性。 1
public void DoFizzBuzz()
for (int number = 1; number &= 100; number++)
var output = GetFizzBuzzOutput(number);
Console.WriteLine(output);
private static string GetFizzBuzzOutput(int number)
string output = string.E
if (number % 3 == 0)
output = &Fizz&;
if (number % 5 == 0)
output += &Buzz&;
if (string.IsNullOrEmpty(output))
output = number.ToString();
}这次感觉怎样?是不是比之前的示例要好些?是不是可读性更好些?什么是更好的代码?首先就是代码要为人来编写,其次是为机器。从长期来看,编写可读性好的代码不会比编写混乱的代码要花费更长的时间。如果你能够非常容易地读懂你写的代码,那么想确认其可以正常工作就更容易了。这应该已经是编写易读代码足够充分的理由了。在很多情况下都需要阅读代码,例如在代码评审中会阅读你写的代码,在你或者其他人修复Bug时会阅读你写的代码,在代码需要修改时也会读到。还有就是当其他人准备在类似的项目或有类似功能的项目中尝试复用你的部分代码时也会先阅读你的代码。“如果你只为你自己写代码,为什么要使代码更具可读性?”好,编写易读的代码最主要的原因是,在未来的一到两周,你将工作在另一个项目上。而此时,有其他人需要修复当前项目的一个Bug,那么将会发生什么?我敢保证他肯定会迷失在你自己编写的恐怖代码中。从我的个人观点来看,好的代码应该拥有以下几个特征:代码容易编写,并易于修改和扩展。代码干净,并表述准确。代码有价值,并注重质量。所以,要时刻考虑先为人来编写代码,然后再满足机器的需要。如何改进可读性?首先,你需要阅读学习其他人编写的代码,来了解什么是好的代码,什么是不好的代码。也就是那些你感觉非常容易理解的代码,和感觉看起来超级复杂的代码。然后,进行实践。最后花费一些时间、经验和实践来改进你的代码的可读性。一般来讲仅通过培训这种方式,在任何软件公司中推动编码规范都有些困难。而诸如结对代码评审,自动化代码评审工具等也可以帮助你。目前流行的工具有:FxCop:对 .NET 代码进行静态代码分析,提供了多种规则来进行不同形式的分析。StyleCop:开源项目,其使用代码风格和一致性规范来对分析C#代码。可在 Visual Studio 中运行,也可以集成到 MSBuild 中。StyleCop 也已经被集成到了一些第三方开发工具中。JetBrains ReSharper:非常著名的提升生产力的工具,可以使 Microsoft Visual Studio IDE 更加强大。全世界的 .NET 开发人员可能都无法想象,工作中怎么能没有 ReSharper 的代码审查、代码自动重构、快速导航和编码助手等这些强大的功能呢。规范是什么?依据维基百科上的描述:“Coding conventions are a set of guidelines for a specific programming language that recommend programming style, practices and methods for each aspect of a piece program written in this language. These conventions usually cover file organization, indentation, comments, declarations, statements, white space, naming conventions, programming practices, programming principles, programming rules of thumb, architectural best practices, etc. These are guidelines for software structural quality. Software programmers are highly recommended to follow these guidelines to help improve the readability of their source code and make software maintenance easier. Coding conventions are only applicable to the human maintainers and peer reviewers of a software project. Conventions may be formalized in a documented set of rules that an entire team or company follows, or may be as informal as the habitual coding practices of an individual. Coding conventions are not enforced by compilers. As a result, not following some or all of the rules has no impact on the executable programs created from the source code.”。你应该能说出属性、局部变量、方法名、类名等的不同,因为它们使用不同的大小写约定,所以这些约定非常有价值。通过互联网,你已经了解了很多相应的准则和规范,你所需要的仅是找到一种规范或者建立你自己的规范,然后始终遵循该规范。下面使用到的源代码(类库设计准则)是由微软的 Special Interest Group 团队开发的,我只是做了些扩展。大小写约定下面是一些关于C#编码标准、命名约定和最佳实践的示例,可以根据你自己的需要来使用。Pascal Casing标示符中的首字母,后续串联的每个单词的首字母均为大写。如果需要,标示符的前几个字母均可大写。Camel Casing标示符的首字母为小写,后续串联的每个单词的首字母为大写。参考:标示符大小写规则一些命名约定示例在互联网上你可以找到足够多的资源,我只是推荐几个其中我最喜欢的:C# 编码约定C# 编码准则C# 编码标准和最佳实践C# 编码规范和命名约定这里我展示了一些最基本的示例,但就像我上面已经提到的,找到一个适合你的规范,然后坚持使用。要使用 Pascal Casing 为类和方法命名。
public class Product
public void GetActiveProducts()
public void CalculateProductAdditinalCost()
}要使用 Camel Casing 为方法的参数和局部变量命名。
public class ProductCategory
public void Save(ProductCategory productCategory)
} 不要使用缩写语。
// Correct
ProductCategory productC
ProductCategory prodC不要在标示符中使用下划线。
// Correct
ProductCategory productC
ProductCategory product_C要在接口名称前使用字母 I 。
public interface IAddress
} 要在类的顶端定义所有成员变量,在最顶端定义静态变量。
public class Product
public static string BrandN
public string Name { }
public DateTime DateAvailable { }
public Product()
}要使用单数的词汇定义枚举,除非是BitField枚举。
public enum Direction
}不要为枚举名称添加Enum后缀。
public enum DirectionEnum
}为什么我们需要编码规范?在大型项目中,开发人员会常依赖于编码规范。他们建立了很多规范和准则,以至于记住这些规范和准则已经变成了日常工作的一部分。计算机并不关心你写的代码可读性是否好,比起读懂那些高级的程序语言语句,计算机更容易理解二进制的机器指令。编码规范提供了很多明显的好处,当然有可能你得到的更多。通常这些项目整体范围的规划,将使能够将精力更多的集中在代码中更重要的部分上。编码规范可以帮助跨项目的传递知识。编码规范可以帮助你在新的项目上更快速的理解代码。编码规范强调组织中关联项目间的关系。你需要编写可读性高的代码,以此来帮助其他人来理解你的代码。代码命名对我们软件开发人员来说是件非常困难的事情,我们在这上面已经花费了大量的时间,并且有太多的需要命名的元素,例如属性、方法、类、文件、项目等。所以我们确实需要花费一些精力在命名规范上,以使名称更有意义,进而提高代码的可读性。还有,编码规范可以让你晚上睡得更香。开发人员最应该遵循的几个规则始终控制类的大小我曾经看到过,并且也曾写过一些超大的类。而且不幸的是,结果总是不好的。后来我找到了真正原因,就是那些超大的类在尝试做太多的事情,这违反了单一职责原则(SRP),也就是面向对象设计原则SOLID&中的&S。“The single responsibility principle states that every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class. All its services should be narrowly aligned with that responsibility.”或者按照&Martin Fowler&的定义:&THERE SHOULD NEVER BE MORE THAN ONE REASON FOR A CLASS TO CHANGE.&为什么一定要将两个职责分离到单独的类中呢?因为每一个职责都是变化的中心。在需求变更时,这个变更将会出现在负责该职责的类中。如果一个类承担了多个职责,就会有一个以上的原因导致其变化。如果一个类有多重职责,则说明这些职责已经耦合到了一起。并且某个职责的变化将有可能削弱或限制这个类满足其他职责的能力。这种耦合将会导致非常脆弱的设计,进而在职责发生变化时,设计可能被意想不到的破坏了。避免过时的注释先说什么过时的注释。按照&Robert C. Martin&的定义:&A comment that has gotten old, irrelevant, and incorrect is obsolete. Comments get old quickly. It is best not to write a comment that will become obsolete. If you find an obsolete comment, it is best to update it or get rid of it as quickly as possible. Obsolete comments tend to migrate away from the code they once described. They become floating islands of irrelevance and misdirection in the code.&针对这个主题,不同水平的开发人员可能都会有自己的见解。我的建议是尝试避免为单独的方法或短小的类进行注释。因为我所见过的大部分的注释都是在尝试描述代码的目的或意图,或者某些注释可能本身就没什么意义。通常开发人员通过写注释来提高代码的可读性和可维护性,但要保证你所写的注释不会成为代码中的噪音。比起注释,我认为合理的方法命名将更为有效,比如你可以为一个方法起一个更有意义的名字。大部分注释都可能变成了无意义的代码噪音,让我们来看看下面这些注释:
//ensure that we are not exporting
//deleted products
if (product.IsDeleted && !product.IsExported)
ExportProducts =
// This is a for loop that prints the 1 million times
for (int i = 0; i & 1000000; i++)
Console.WriteLine(i);
}如果我们不写注释,而是命名一个方法,比如叫 CancelExportForDeletedProducts() ,情况会怎样?所以,合适的方法命名比注释更有效。然而某些情况下,代码注释也会非常有帮助,比如 Visual Studio 会从注释生成 API 文档。此处的注释略有不同,你需要使用 “///” 标识符来注释,这样其他开发人员才能看到 API 或类库的智能提示。我没有说总是要避免注释。按照 Kent Beck 说法,可以使用更多的注释来描述程序整体是如何工作的,而不是对单独的方法进行注释。如果注释是在尝试描述代码的目的或意图,那就错了。如果你在代码中看到了密密麻麻的的注释,你可能就会意识到有这么多注释说明代码写的很糟糕。了解更多信息可以阅读下面这几本书:《Professional Refactoring in C# and ASP.NET》 by Danijel Arsenovski《重构:改善既有代码设计》 by Martin Fowler, Kent Beck, John Brant, William Opdyke, Don Roberts避免不必要的RegionRegion 是 Visual Studio 提供的一个功能,它允许你将代码分块。Region 的存在是因为它可以使大文件导航变得容易。Region 还常被用于隐藏丑陋的代码,或者类已经膨胀的非常大了需要分块。而如果一个类做了太多的事情,也就说明其违反了单一职责原则。所以,下次当你想新增一个 Region 时,先考虑下有没有可能将这个 Region 分离到一个单独的类中。保持方法的短小方法中的代码行数越多,则方法越难理解。我们推荐每个方法中只包含 20-25 行代码。但有些人说 1-10 行更合理,这只是些个人喜好,没有硬性的规则。抽取方法是最常见的重构方式之一。如果你发现一个方法过长,或者已经需要一个注释来描述它的目的了,那么你就可以应用抽取方法了。人们总是会问一个方法到底多长合适,但其实长度并不是问题的根源。当你在处理复杂的方法时,跟踪所有局部变量是最复杂和消耗时间的,而通过抽取一个方法可以节省一些时间。可以使用 Visual Studio 来抽取方法,它会帮助你跟踪局部变量,并将其传递给新的方法或者接收方法的返回值。Using ReSharperUsing Microsoft Visual Studio更多的信息可以参考&MSDN。按照《重构:改善既有代码设计》中的描述,&Extract Method is one of the most common refactoring I do. I look at a method that is too long or look at code that needs a comment to understand its purpose. I then turn that fragment of code into its own method. I prefer short, well-named methods for several reasons. First, it increases the chances that other methods can use a method when the method is finely grained. Second, it allows the higher-level methods to read more like a series of comments. Overriding also is easier when the methods are finely grained. It does take a little getting used to if you are used to seeing larger methods. And small methods really work only when you have good names, so you need to pay attention to naming. People sometimes ask me what length I look for in a method. To me length is not the issue. The key is the semantic distance between the method name and the method body. If extracting improves clarity, do it, even if the name is longer than the code you have extracted.&避免过多的参数通过声明一个类来代替多个参数。创建一个类,用于包含所有的参数。通常来讲,这是一个较好的设计,并且这个抽象非常的有价值。
public void Checkout(string shippingName, string shippingCity,
string shippingSate, string shippingZip, string billingName,
string billingCity, string billingSate, string billingZip)
public void Checkout(ShippingAddress shippingAddress, BillingAddress billingAddress)
}我们需要引入类来代替所有的参数。避免复杂的表达式
if(product.Price&500 && !product.IsDeleted &&
!product.IsFeatured && product.IsExported)
// do something
}复杂的表达式意味着其背后隐藏了一些涵义,我们可以通过使用属性来封装这些表达式,进而使代码更易读些。把警告等同于错误如果你注意看代码,你会发现一个变量被声明了但从没被使用过。正常来讲,我们编译工程后会得到一个警告,但仍可以运行工程而不会发生任何错误。但是我们应该尽可能地移除这些警告。通过如下步骤可以在工程上设置将警告等同于错误:精简多处返回在每段程序中都减少函数返回的数量。假设从底部开始阅读代码,你很难意识到有可能在上面的某处已经返回了,这样的代码将是非常难理解的。仅使用一处返回可以增强可读性。如果程序这么写的话可能看起来比较干净,但不立即返回也意味着需要编写更多代码。
if(product.Price&15)
else if(product.IsDeleted)
else if(!product.IsFeatured)
var isValid =
if(product.Price&15)
else if(product.IsDeleted)
else if(!product.IsFeatured)
return isV你可以想象在这 20-30 行代码中就散落了 4 个退出点,这会使你非常难理解到底程序内部做了什么,到底会执行什么,什么时候执行。关于这一点我得到了很多人的回复,一些人同意这个观点,有些则不同意这是一个好的编码标准。为了找出潜在的问题,我做了些单元测试,发现如果复杂的方法包含多个退出点,通常情况下会需要一组测试来覆盖所有的路径。
if( BADFunction() == true)
// expression
if( anotherFunction() == true )
// expression
if( !GoodFunction())
return false
// expression
if( !GoodFunction2())
// more expression
进一步理解可以参考&Steve McConnell 的《代码大全》。使用断言在软件开发中,断言代码常被用于检查程序代码是否按照其设计在执行。通常 True 代表所有操作按照预期的完成,False 代表已经侦测到了一些意外的错误。断言通常会接收两个参数,一个布尔型的表达式用于一个描述假设为真的假定,一个消息参数用于描述断言失败的原因。尤其在开发大型的、复杂的高可靠系统中,断言通常是非常有用的功能。例如:如果系统假设将最多支持 100,000 用户记录,系统中可能会包含一个断言来检查用户记录数小于等于 100,000,在这种范围下,断言不会起作用。但如果用户记录数量超过了 100,000,则断言将会抛出一个错误来告诉你记录数已经超出了范围。检查循环端点值一个循环通常会涉及三种条件值:第一个值、中间的某值和最后一个值。但如果你有任何其他的特定条件,也需要进行检测。如果循环中包含了复杂的计算,请不要使用计算器,要手工检查计算结果。总结通常在任何软件公司中推行编码规范都需要按照组织行为、项目属性和领域来进行,在此我想再次强调“找到一个适合你的编码规范,并一直遵循它”。如果你认为我遗漏了某个特别有用的编码准则,请在评论中描述,我会尝试补充到文章中。
05-2604-2904-2704-2604-2404-2402-2501-2901-2301-21
阅读本文后您有什么感想? 已有23人给出评价!
名称大小下载中国领先的IT技术网站
51CTO旗下网站
提高代码质量:如何编写函数
本文从函数命名,函数参数和函数的代码编写三个方面谈了关于如何编写好一个函数的感受和想法。文中提到了很多具体的情况,当然日常编码中肯定会遇到更多复杂的情况可能我暂时没有想到。
作者:来源:| 11:03
函数是实现程序功能的最基本单位,每一个程序都是由一个个最基本的函数构成的。写好一个函数是提高程序代码质量最关键的一步。本文就函数的编写,从函数命名,代码分布,技巧等方面入手,谈谈如何写好一个可读性高、易维护,易测试的函数。
首先从命名说起,命名是提高可读性的第一步。如何为变量和函数命名一直是开发者心中的痛点之一,对于母语非英语的我们来说,更是难上加难。下面我来说说如何为函数命名的一些想法和感受:
采用统一的命名规则
在谈及如何为函数取一个准确而优雅的名字之前,首先最重要的是要有统一的命名规则。这是提高代码可读性的最基础的准则。
帕斯卡命名法和驼峰命名法是目前比较流行的两种规则,不同语言采用的规则可能不一样,但是要记住一点:保持团队和个人风格一致。
1、帕斯卡命名法
帕斯卡命名法简单地说就是:多个单词组成一个名称时,每个单词的首字母大写。比如:
public&void&SendMessage&();&public&void&CalculatePrice&();&
在C#中,这种命名法常用于类、属性,函数等等,在JS中,构造函数也推荐采用这种方式命名。
2、驼峰命名法
驼峰命名法和帕斯卡命名法很类似,多个单词组成一个名称时,第一个单词全部小写,后面单词首字母大写。比如:
var&sendMessage&=&unction&()&{};&var&calculatePrice&=&function&()&{};&
驼峰命名法一般用于字段、局部变量、函数参数等等。,在JS中,函数也常用此方法命名。
采用哪种命名规则并不绝对,最重要的是要遵守团队约定,语言规范。
尽可能完整地描述函数所做的所有事情
有的开发者可能觉得相较于长函数名来说,短函数名看起来可能更简洁,看起来也更舒服。但是通常来说,函数名称越短其描述的意思越抽象。函数使用者对 函数的第一印象就是函数名称,进而了解函数的功能,我们应该尽可能地描述到函数所做的所有事情,防止使用者不知道或误解造成潜在的错误。
举个例子,假设我们做一个添加评论的功能,添加完毕后并返回评论总数量,如何命名比较合适呢?
&var&count&=&function&addComment()&{}&&var&count&=&function&addCommentAndReturnCount()&{};&
这只是简单的一个例子,实际开发中可能会遇到得更多复杂的情况,单一职责原则是我们开发函数要遵守的准则,但是有时候无法做到函数单一职责时,请记 得函数名应该尽可能地描述所有事情。当你无法命名一个函数时,应该分析一下,这个函数的编写是否科学,有什么办法可以去优化它。
采用准确的描述动词
这一点对母语非英语的开发者来说应该是比较难的一点,想要提高这方面的能力,最主要的还是要提高词汇量,多阅读优秀代码积累经验。
这里简单说说我自己的一些感想和看法:
1、不要采用太抽象广泛的单词
很多开发人员会采用一个比较宽泛的动词来为函数命名,最典型的一个例子就是get这个单词。我们平时开发中经常会通过各种不同的方式拿到数据,但是每一种方式都用get就有点太抽象了。具体如何命名,要具体分析:
(1)简单的返回数据
Person.prototype.getFullName&=&function()&{&return&this.firstName&=&this.lastN&}&
(2)从远程获取数据
var&fetchPersons&=&function&()&{&&...&&&&&$.ajax({&&})&}&
(3)从本地存储加载数据
var&loadPersons&=&function&()&{};&
(4)通过计算获取数据
var&calculateTotal&=&function&()&{};&
(5)从数组中查找数据
var&findSth&=&function&(arr)&{};&
(6)从一些数据生成或得到
var&createSth&=&function&(data)&{};&var&buildSth&=&function&(data)&{};&var&parseSth&=&function(data)&{};&
这是一个简单的例子,我们平时开发中遇到的情况肯定会复杂得多,关键还是靠单词的积累,多阅读优秀源码
下面是整理的一些常用的对仗词,大家可以参考使用
add/remove&&&&&&&&increment/decrement&&&&&&&open/close&begin/end&&&&&&&&&&&&insert/delete&&&&&&&&&&&&&&&&&&&&&&show/hide&create/destory&&&&lock/unlock&&&&&&&&&&&&&&&&&&&&&&&&source/target&first/last&&&&&&&&&&&&&&min/max&&&&&&&&&&&&&&&&&&&&&&&&&&&&&star/stop&get/put&&&&&&&&&&&&&&&&next/previous&&&&&&&&&&&&&&&&&&&&&up/down&&&&&get/set&&&&&&&&&&&&&&&&old/new&
根据不同项目和需求制定好命名规则
这一点也是很重要的,尤其是在团队合作中,不同的项目和需求可能导致的不同的命名规则。
比如我们通常采用的命名规则是动宾结构,也就是动词在前,名词灾后。但是有一些项目,比如数据接口等项目中,有的团队会采用名字在前,动词在后的形式,例如:
public&static&Product[]&ProductsGet(){};&public&static&Product[]&ProductsDel(){};&public&static&Customer[]&CustomerDel(){};&public&static&Customer[]&CustomerDel(){};&
这种的好处是看到前面的名词,比如ProductsGet,就能很快的知道这是产品相关的数据接口。
当然这个并不是绝对的,关键还是要团队共同制定和遵守同一套命名规则。
函数使用者在调用函数时,必须严格遵守函数定义的参数,这对函数的易用性,可测试性等方面都是至关重要的。下面我从几个方面来谈谈关于如何优化好函数参数的一些想法。
毫无疑问,函数参数越多,函数的易用性就越差,因为使用者需要严格眼中参数列表依次输入参数,如果某个参数输错,将导致不可意料的结果。
但是,函数参数就一定越少越好吗?我们来看看下面的例子:
var&count&=&0;&var&unitPrice&=&1.5;&....&...&var&calculatePrice&=&function&()&{&&&& return&count&*&unitP&}&
在这个例子中,我们通过calculatePrice这个函数来计算价格,函数不接收任何参数,直接通过两个全局变量unitPrice和 count进行计算。这种函数的定义对使用者来说非常方便,直接调用即可,不用输入任何参数。但是这里可能会有潜在的bug:全局变量可能在其他地方被修 改成其他值了,难以进行单元测试等等问题。所以,这个函数可以传入数量和价格信息:
var&calculatePrice&=&function(count,&unitPrice)&{&&&&&return&count&*&unitP&}&
这种方式下,函数使用者在使用时,要传入参数进行调用,避免了全局变量可能存在的问题。另外也降低了耦合,提高了可测试性,在测试的时候就不必依赖于全局变量。
当然,在保证函数不依赖于全局变量和测试性的情况下,函数参数还是越少越好。《代码大全》中提出将函数的参数限制在7个以内,这个可以作为我们的参考。
有的时候,我们不可避免地要使用超过10个以上函数,在这中情况下,我们可以考虑将类似的参数构造成一个类,我们来看看一个典型的例子。
我相信大家平时一定做过这样的功能,列表筛选,其中涉及到各种条件的筛选,排序,分页等等功能,如果将参数一个一个地列出来必定会很长,例如:
var&filterHotel&=&function&(city,&checkIn,&checkOut,&price,&star,&position,&wifi,&meal,&sort,&pageIndex)&{}&
这是一个筛选酒店的函数,其中的参数分别是城市,入住和退房时间,价格,星级,位置,是否有wifi,是否有早餐,排序,页码等等,实际的情况可能会更多。在这种参数特别多的情况下,我们可以考虑将一些相似的参数提取成类出来:
function&DatePlace&(city,&checkIn,&checkOut){&&&&&this.city&=&&&&&&this.checkIn&=&checkIn;&&&&&&this.checkOut&=&checkOut&}&function&HotelFeature&(price,&star,&position,&wifi,&meal){&&&&&this.price&=&&&&&&this.star&=&&&&&&&this.position&=&&&&&&this.wifi&=&&&&&&this.meal&=&&&}&&var&filterHotel&=&function&(datePlce,&hotelFeature,&sort,&pageIndex)&{};&
将多个参数提取成对象了,虽然对象数量增多了,但是函数参数更清晰了,调用起来也更方便了。
尽量不要使用bool类型作为参数
有的时候,我们会写出使用bool作为参数的情况,比如:
var&getProduct&=&function(finished)&{&&&&if(finished){&&&&}&&&else{&&&&}&&}&&getProduct(true);&
如果没有注释,使用者看到这样的代码:getProduct(true),他肯定搞不清楚true是代表什么意思,还要去查看函数定义才能明白这个函数是如何使用的。这就意味着这个函数不够清晰,就应该考虑去优化它。通常有两种方式去优化它:
(1)将函数一分为二,分成两个函数getFinishedProduct和getUnFinishedProduct
(2)将bool转换成有意义的枚举getProduct(ProductStatus)
不要修改输入参数
如果输入参数在函数内被修改了,很有可能造成潜在的bug,而且使用者不知道调用函数后居然会修改函数参数。
正确使用输入参数的做法应该是只传入参数用于函数调用。
如果不可避免地要修改,一定要在注释中说明。
尽量不要使用输出参数
使用输出参数说明这个函数不只做了一件事情,而且使用者使用的时候可能还会感到困惑。正确的方式应该是分解函数,让函数只做一件事。
编写函数体
函数体就是实现函数功能的整个逻辑,是一个函数最关键的地方。下面我谈谈关于函数代码编写的一些个人想法。
相关操作放在一起
有的时候,我们会在一个函数内进行一系列的操作来完成一个功能,比如:
var&calculateTotalPrice&=&function()&&{&&&&var&roomCount&=&getRoomCount();&&&&var&mealCount&=&getMealCount();&&&&&var&roomPrice&=&getRoomPrice(roomCount);&&&&var&mealPrice&=&getMealPrice(mealCount);&&&&return&roomPrice&+&mealP&}&
这段代码计算了房间价格和早餐价格,然后将两者相加返回总价格。
这段代码乍一看,没有什么问题,但是我们分析代码,我们先是分别获取了房间数量和早餐数量,然后再通过房间数量和早餐数量分别计算两者的价格。这种 情况下,房间数量和计算房间价格的代码分散在了两个位置,早餐价格的计算也是分散到了两个位置。也就是两部分相关的代码分散在了各处,这样阅读起代码来逻 辑会略显不通,代码组织不够好。我们应该让相关的语句和操作放在一起,也有利于重构代码。我们修改如下:
var&calculateTotalPrice&=&function()&&{&&&&var&roomCount&=&getRoomCount();&&&&var&roomPrice&=&getRoomPrice(roomCount);&&&&var&mealCount&=&getMealCount();&&&var&mealPrice&=&getMealPrice(mealCount);&&&return&roomPrice&+&mealP&}&
我们将相关的操作放在一起,这样代码看起来更清晰了,而且也更容易重构了。
尽量减少代码嵌套
我们平时写if,switch或for语句是常有的事儿,也一定写过多层if或for语句嵌套的情况,如果代码里的嵌套超过3层,阅读起来就会非常困难了。我们应该尽量避免代码嵌套多层,最好不要超过2层。下面我来说说我平时一些减少嵌套的技巧或方法。
if语句嵌套的问题
多层if语句嵌套是常有的事情,有什么好的方法可以减少嵌套呢?
1、尽早终止函数或返回数据
如果符合某个条件下可以直接终止函数,则应该将这个条件放在第一位。我们来看看下面的例子。
&if(condition1)&{&&&& if(condition2){&&&&&&&& if(condition3){&&&&&&&& }&&&&&&&& else{&&&&&&&&&&&& return;&&&&&&&&& }&&&&&&& }&&& else{&&&&&&&& return;&&&& }&&&&&}&else&{&&&& return;&&}&
这段代码中if语句嵌套了3层,看起来已经很复杂了,我们可以将最后面的return提取到最前面去。
&if(!condition1){&&return;& }&if(!condition2){&&&& return;&}&&if(!condition3){&&&&& return;&&}&&&
这段代码中,我们把condition1等于false的语句提取到前面,直接终止函数,将多层嵌套的if语句重构成只有一层if语句,代码也更清晰了。
注意:一般情况下,我们写if语句会将条件为true的情况写在前面,这也比较符合我们的思维习惯。如果是多层嵌套的情况,应该优先减少if语句的嵌套
2、不适用if语句或switch语句
条件语句一般来说是不可避免的,有的时候,我们要判断很多条件就会写很多if-elseif语句,嵌套的话,就更加麻烦了。如果有一天增加了新需 求,我们就要去增加一个if分支语句,这样不仅修改起来麻烦,而且容易出错。《代码大全》提出的表驱动法可以有效地解决if语句带来的问题。我们来看下面 这个例子:
if(condition&==&&case1&){&&&& return&1;&&}&&elseif(condition&==&&case2&){&&&&& return&2;&&}&elseif(condition&==&&case3&){&&&&& return&3;&&}&&elseif(condition&==&&case4&){&&&&& return&4;&&}&
这段代码分别依次判断了四种情况,如果再增加一种情况,我们就要再新增一个if分支,这样就可能造成潜在的问题,如何去优化这段代码呢?我们可以采用一个Map或Dictionary来将每一种情况和相应值一一对应。
var&map&=&{&&&&case1&:1,&&&&case2&:2,&&&&case3&:3,&&&&case4&:4&}&return&map[condition];&
通过map优化后,整个代码不仅更加简洁,修改起来也更方便而且不易出错了。
当然,很多时候我们的条件判断语句并不是这么简单的,可能会涉及到复杂的逻辑运算,大家可以查看《代码大全》第18章,其中有详细的介绍。
3、提取内层嵌套为一个函数进行调用
多层嵌套的时候,我们还可以将内层嵌套提取到一个新的函数中,然后调用该函数,这样代码也就更清晰了。
for循环嵌套优化
for循环嵌套相比于if嵌套来说更加复杂,阅读起来会更麻烦,下面说说几点要注意的东西:
1、最多只能两层for循环嵌套
2、提取内层循环到新函数中
3、多层循环时,不要简单地位索引变量命名为i,j,k等,容易造成混淆,要有具体的意思
提取复杂逻辑,语义化
有的时候,我们会写出一些比较复杂的逻辑,阅读代码的人看到后可能搞不清楚要做什么,这个时候,就应该提取出这段复杂的逻辑代码。
if&(age&&&18&&&&gender&==&&man&)&{&&&&&}&
这段代码表示当年龄大于18并且是男性的话,可以doSth,但是还是不够清晰,可以将其提取出来
&var&canDoSth&=&function&(age,&gender){&&&&&return&age&&&18&&&&gender&==&&man&;&&}&...&...&...&if(canDoSth(age,&gender)){&&&&&&&}&
虽说多了一个函数,但是代码更加清晰和语义化了。
本文从函数命名,函数参数和函数的代码编写三个方面谈了关于如何编写好一个函数的感受和想法。文中提到了很多具体的情况,当然日常编码中肯定会遇到更多复杂的情况可能我暂时没有想到。我简单的归纳了几点:
1、准确地对变量、函数命名
2、不要有重复逻辑的代码
3、函数的行数不要超过20行,这里的20行只是个大概,并不一定是这个数字
4、减少嵌套
我相信大家一定会很多关于这方面的经验,欢迎进行交流,共同提高代码质量。
【编辑推荐】【责任编辑: TEL:(010)】
大家都在看猜你喜欢
原创头条头条头条头条
24H热文一周话题本月最赞
讲师:30600人学习过
讲师:119785人学习过
讲师:266679人学习过
精选博文论坛热帖下载排行
本书是一本真正意义上的网络系统设计图书,从网络系统设计角度全面介绍了整个网络系统设计的思路和方法,而不是像传统网络集成类图书那样主...
订阅51CTO邮刊

我要回帖

更多关于 零基础如何写代码 的文章

 

随机推荐