找回密码
 申请新用户
搜索
热搜: 活动 交友 discuz
查看: 8601|回复: 1

编程中的命名设计那点事

[复制链接]
发表于 2010-4-8 14:42:32 | 显示全部楼层 |阅读模式
转自:http://coolshell.cn/?p=990

在我开始设计系统的时候,我会花去很多时间去设计命名,因为好的命名和好的设计是分不开的。

In the beginning was the Word, and the Word was with God, and the Word was God
太初有道。道与神同在,道就是神。 (约翰福音第一章,第一节)

在设计过程中给类,方法和函数好的命名会带来好的设计,虽然这不是一定成立,但是如果坏的命名那一定不会给你带来好的设计。在设计过程,如果你发现你很难命名某一个模块,某个方法时,可能你真正遇到的问题不是难命名的问题,而是这个设计是否真的合理,你或许应该花更多的时间来重新设计一下你的模块。

好的命名不仅会带来好的设计,好的命名还提高了程序的可读性,降低代码维护的成本。另一方面,如果糟糕的命名会给代码带来一堵无形的墙,让你必须深入代码去研究代码具有的行为,增加你理解代码的时间。

为此我总结了几条关于命名的指导原则,希望这几条原则能为你的命名设计带来帮助,我使用的是C++的语法,当然这些原则也很容易扩展到其他语言中去。

类型命名(类,接口,和结构)


名字应该尽量采用名词
Bad:           Happy
Good:          Happiness


不要使用类似名字空间的前缀
Bad:           SystemOnlineMessage
Good:          System::Online:Message

形容词不要用太多,能描述清楚就行
Bad:           IAbstractFactoryPatternBase
Good:          IFactory

在类型中不要使用Manager 或则 Helper 或则其他没意义的单词
如果你一定要在一个类型上加上Manager或Helper,那么这个类型要么就是命名的非常糟糕,要么就是设计的非常糟糕,如果是后则,那么这个类型就应该管理manage和帮助help一下自己了。
Bad:           ConnectionManager
               XmlHelper
Good:          Connection
               XmlDocument, XmlNode, etc.

如果某个类不能通过简单的命名来描述它具有的功能,可以考虑用类比的方式来命名
Bad:           IncomingMessageQueue
               CharacterArray
               SpatialOrganizer
Good:          Mailbox
               String
               Map

如果你使用类比,你就应该一致的使用它们
Bad:           Mailbox,DestinationID
Good:          Mailbox,Address

函数(方法和过程)


简洁
Bad:           list.GetNumberOfItems()
Good:          list.Count()

不要太简洁
Bad:           list.Verify()
Good:          list.ContainsNull()

避免缩写
Bad:           list.Srt()
Good:          list.Sort()

对于完成某件事情的函数使用动词
Bad:           obj.RefCount();
Good:          list.Clear();
               list.Sort();
               obj.AddReference();

对于返回布尔型的函数,使用类似提问的方式
Bad:           list.Empty();
Good:          list.IsEmpty();
               list.Contains(item);

对于只是返回属性,而不改变状态的函数则使用名词
Bad:           list.GetCount();
Good:          list.Count();

不要在函数名字中重复参数的名称
Bad:           list.AddItem(item);
               handler.ReceiveMessage(msg);
Good:          list.Add(item);
               handler.Receive(msg);

不要方法的名字中重复此方法的类的名称
Bad:           list.AddToList(item);
Good:          list.Add(item);

不要在函数的名字中加入返回类型,除非函数名必须以返回类型进行区别
Bad:           list.GetCountInt();
Good:          list.GetCount();
               message.GetIntValue();
               message.GetFloatValue();

不要名字中使用And 或则 Or
如果你使用一个连接词来连接函数名,那么这个函数肯定是做了太多的事情,更好的做法是将其分成更小的函数来处理(类似面向对象设计准则中的责任单一原则)。
如果你想确保是这是一个原子的操作,那么你应该用一个名字来描述这个操作或一个类来封装他
Bad:           mail.VerifyAddressAndSendStatus();
Good:          mail.VerifyAddress();
               mail.SendStatus();

这是一篇非常优秀的文章,我用我的语言在组织了一下,如果喜欢英文的读者可以点击这里阅读原文

 楼主| 发表于 2010-4-8 14:43:25 | 显示全部楼层
转载:http://journal.stuffwithstuff.com/2009/06/05/naming-things-in-code/Naming Things in Code
code | language2009 / 06 / 05

When I’m designing software, I spend a lot of time thinking about names. For me, thinking about names is inseparable from the process of design. To name something is to define it.

In the beginning was the Word, and the Word was with God, and the Word was God.

The Gospel According to John

One of the ways I know a design has really clicked is when the names feel right. It may take some time for this to happen (I rename things a lot when I’m first putting them down in code), but that’s OK. Good design doesn’t happen fast.

Of course, good names alone don’t make a good design, but it’s been my experience that crappy names do prevent one. With that in mind, here’s the guidelines I try to follow when naming things. The examples here are in C++, but work more or less for any language.

Types (Classes, Interfaces, Structs)The name should be a noun phrase.
  • Bad:  Happy  
  • Good: Happiness  

Do not use namespace-like prefixes.

That’s what namespaces are for.

  • Bad:  SystemOnlineMessage  
  • Good: System::Online::Message  

Use just enough adjectives to be clear.
  • Bad:  IAbstractFactoryPatternBase  
  • Good: IFactory  

Do not use “Manager” or “Helper” or other null words in a type name.

If you need to add “Manager” of “Helper” to a type name, the type is either poorly named or poorly designed. Likely the latter. Types should manage and help themselves.

  • Bad:  ConnectionManager  
  •       XmlHelper  
  • Good: Connection  
  •       XmlDocument, XmlNode, etc.  

If a class doesn’t represent something easily comprehensible, consider a concrete metaphor.
  • Bad:  IncomingMessageQueue  
  •       CharacterArray  
  •       SpatialOrganizer  
  • Good: Mailbox  
  •       String  
  •       Map  

If you use a metaphor, use it consistently.
  • Bad:  Mailbox, DestinationID  
  • Good: Mailbox, Address  

Functions (Methods, Procedures)Be terse.
  • Bad:  list.GetNumberOfItems();  
  • Good: list.Count();  

Don’t be too terse.
  • Bad:  list.Verify();  
  • Good: list.ContainsNull();  

Avd abbrvtn.
  • Bad:  list.Srt();  
  • Good: list.Sort();  

Name functions that do things using verbs.
  • Bad:  obj.RefCount();  
  • Good: list.Clear();  
  •       list.Sort();  
  •       obj.AddReference();  

Name functions that return a boolean (i.e. predicates) like questions.
  • Bad:  list.Empty();  
  • Good: list.IsEmpty();  
  •       list.Contains(item);  

Name functions that just return a property and don’t change state using nouns.
  • Bad:  list.GetCount();  
  • Good: list.Count();  

(In C#, you’d actually use properties for this.)

Don’t make the name redundant with an argument.
  • Bad:  list.AddItem(item);  
  •       handler.ReceiveMessage(msg);  
  • Good: list.Add(item);  
  •       handler.Receive(msg);  

Don’t make the name redundant with the object.
  • Bad:  list.AddToList(item);  
  • Good: list.Add(item);  

Only describe the return in the name if there are identical functions that return different types.
  • Bad:  list.GetCountInt();  
  • Good: list.GetCount();  
  •       message.GetIntValue();  
  •       mmessage.GetFloatValue();  

Don’t use “And” or “Or” in a function name.

If you’re using a conjunction in the name, the function is likely doing too much. Break it into smaller pieces and name accordingly.

If you want to ensure this is an atomic operation, consider creating a name for that entire operation, or possibly a class that encapsulates it.

  • Bad:  mail.VerifyAddressAndSendStatus();  
  • Good: mail.VerifyAddress();  
  •       mail.SendStatus();  

Does it Matter?

Yes, I firmly believe it does. A module with well-named parts quickly teaches you what it does. By reading only a fraction of the code, the you’ll quickly build a complete mental model of the whole system. If it calls something a “Mailbox” you’ll expect to see “Mail”, and “Addresses” without having to read the code for them.

Well-named code is easier to talk about with other programmers, helping knowledge of the code to spread. No one wants to try to say “ISrvMgrInstanceDescriptorFactory” forty times in a meeting.

Over on the other side, poor names create an opaque wall of code, forcing you to painstakingly run the program in the your head, observe its behavior and then create your own private nomenclature. “Oh, DoCheck() looks like it’s iterating through the connections to see if they’re all live. I’ll call that ‘AreConnectionsLive()’.” Not only is this slow, it’s non-transferrable.

From the code I’ve seen, there’s a strong correspondence between a cohesive set of names in a module, and a cohesive module. When I have trouble naming something, there’s a good chance that what I’m trying to name is poorlydesigned. Maybe it’s trying to do too many things at once, or is missing a critical piece to make it complete.

It’s hard to tell if I’m designing well, but one of the surest guides I’ve found that I’m not doing it well is when the names don’t come easy. When I design now, I try to pay attention to that. Once I’m happy with the names, I’m usually happy with the design.



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 申请新用户

本版积分规则

守望轩 ( 湘ICP备17013730号-2 )|网站地图

GMT+8, 2024-4-25 13:34 , Processed in 0.044559 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表