• 编程中的命名设计那点事(转)


    转自: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();

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

     以下是英文原文:

    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.

    1. Bad:  Happy   
    2. Good: Happiness  
    Bad:  Happy
    Good: Happiness
    

    Do not use namespace-like prefixes.

    That’s what namespaces are for.

    1. Bad:  SystemOnlineMessage   
    2. Good: System::Online::Message  
    Bad:  SystemOnlineMessage
    Good: System::Online::Message
    

    Use just enough adjectives to be clear.

    1. Bad:  IAbstractFactoryPatternBase   
    2. Good: IFactory  
    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.

    1. Bad:  ConnectionManager   
    2.       XmlHelper   
    3. Good: Connection   
    4.       XmlDocument, XmlNode, etc.  
    Bad:  ConnectionManager
          XmlHelper
    Good: Connection
          XmlDocument, XmlNode, etc.
    

    If a class doesn’t represent something easily comprehensible, consider a concrete metaphor.

    1. Bad:  IncomingMessageQueue   
    2.       CharacterArray   
    3.       SpatialOrganizer   
    4. Good: Mailbox   
    5.       String   
    6.       Map  
    Bad:  IncomingMessageQueue
          CharacterArray
          SpatialOrganizer
    Good: Mailbox
          String
          Map
    

    If you use a metaphor, use it consistently.

    1. Bad:  Mailbox, DestinationID   
    2. Good: Mailbox, Address  
    Bad:  Mailbox, DestinationID
    Good: Mailbox, Address
    

    Functions (Methods, Procedures)

    Be terse.

    1. Bad:  list.GetNumberOfItems();   
    2. Good: list.Count();  
    Bad:  list.GetNumberOfItems();
    Good: list.Count();
    

    Don’t be too terse.

    1. Bad:  list.Verify();   
    2. Good: list.ContainsNull();  
    Bad:  list.Verify();
    Good: list.ContainsNull();
    

    Avd abbrvtn.

    1. Bad:  list.Srt();   
    2. Good: list.Sort();  
    Bad:  list.Srt();
    Good: list.Sort();
    

    Name functions that do things using verbs.

    1. Bad:  obj.RefCount();   
    2. Good: list.Clear();   
    3.       list.Sort();   
    4.       obj.AddReference();  
    Bad:  obj.RefCount();
    Good: list.Clear();
          list.Sort();
          obj.AddReference();
    

    Name functions that return a boolean (i.e. predicates) like questions.

    1. Bad:  list.Empty();   
    2. Good: list.IsEmpty();   
    3.       list.Contains(item);  
    Bad:  list.Empty();
    Good: list.IsEmpty();
          list.Contains(item);
    

    Name functions that just return a property and don’t change state using nouns.

    1. Bad:  list.GetCount();   
    2. Good: list.Count();  
    Bad:  list.GetCount();
    Good: list.Count();
    

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

    Don’t make the name redundant with an argument.

    1. Bad:  list.AddItem(item);   
    2.       handler.ReceiveMessage(msg);   
    3. Good: list.Add(item);   
    4.       handler.Receive(msg);  
    Bad:  list.AddItem(item);
          handler.ReceiveMessage(msg);
    Good: list.Add(item);
          handler.Receive(msg);
    

    Don’t make the name redundant with the object.

    1. Bad:  list.AddToList(item);   
    2. Good: list.Add(item);  
    Bad:  list.AddToList(item);
    Good: list.Add(item);
    

    Only describe the return in the name if there are identical functions that return different types.

    1. Bad:  list.GetCountInt();   
    2. Good: list.GetCount();   
    3.       message.GetIntValue();   
    4.       mmessage.GetFloatValue();  
    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.

    1. Bad:  mail.VerifyAddressAndSendStatus();   
    2. Good: mail.VerifyAddress();   
    3.       mail.SendStatus();  
    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 poorly designed. 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.

  • 相关阅读:
    Linux makefile 教程 很具体,且易懂
    Java串口通信具体解释
    今年股票注定有一波行情(重申6月10号的观点)
    hotmail邮箱pop3server设置方法
    html的下拉框的几个基本使用方法
    第1次实验——NPC问题(回溯算法、聚类分析)
    【甘道夫】Hive 0.13.1 on Hadoop2.2.0 + Oracle10g部署详细解释
    C该程序生成一个唯一的序列号
    高速分拣(1)的基本算法
    Eclipse项目崩溃,使用MyEclipse解决
  • 原文地址:https://www.cnblogs.com/submarinex/p/1941258.html
Copyright © 2020-2023  润新知