`
dianziermu
  • 浏览: 140634 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

良好的Java风格

    博客分类:
  • J2SE
阅读更多

简介


多年来,作为一名软件开发者和顾问,我看到过各种程序语言编写的大量代码。其中有书写优雅的,也有书写丑陋的,不幸的是很 多代码都属于后者。我希望说服你和我的开发伙伴我们应该在代码风格上给予更多的关注,就像我们关注用户界面和应用程序的其它部分那样。这一系列由两部分组 成,在第一部分中,我将解释为什么我们应该关心代码看起来到底是什么样子,并向你展示良好Java风格的一些基本要素。

为什么风格如此重要


虽然Java是用来写程序而不是写散文的,但它也是用来表达思想和想法的。而且,除了传递信息,这些思想和想法也必须确实在解决一些问题。也许你会顾虑好的风格或许会像是在浪费时间,但它可以让我们在代码中表达的思想和想法格外的清晰。


这里是使用良好风格的一些理由[来自"Java Code Conventions," Sun Microsystems]:

一个软件产品一生80%的花费是在维护上。
任何软件都几乎不可能一生都由软件的原作者来维护。
好的风格能够提高软件代码的可维护性。
如果软件还附带源码的话,那它应该像产品的其它部分那样结构良好,清晰,专业。


以良好的风格编写代码还有下面这些好处:

提高代码的可阅读性,连贯性和一致性,这样使代码容易理解和维护。
易于跟踪和调试,因为代码是清晰和连贯的。
易于从你或别的程序员停止的地方继续编写代码,特别是经过较长的一段时间以后。
提高代码指南的价值,因为参与者可以更加集中注意力去了解代码正在做什么。

一般原则


以良好的风格编写Java并不困难,但确实需要注意细节。这里是一些应该遵守的一般原则:

使代码清晰并易于阅读。
使代码一致。
使用明显的标识符。
有逻辑地组织文件和类。
每个文件只有一个类(不包括内部类)。
最大行宽在80-90个字符之间。
使用空格和(或)其它易于判断的分隔符。
缩进使用空格而不是制表符。

制表符 vs. 空格


制表符 vs. 空格是一个有关编写代码的严谨问题,我并不想让你认为只有一种正确方式。我赞成使用空格是因为它确保我的代码在我的编辑器里和在你的编辑器里看起来一样,反之亦然。如果你感觉使用空格而不是制表符“就是不对”,那么就用制表符吧。

大括号和缩进


缩进风格(参看,Raymond, "Indent Style")或者大括号("{" 和 "}")和相关的代 码缩进是另一个关于编写代码的严谨问题。像Java这种C风格的编程语言,有很多种缩进风格,并且我也不想说它们其中的哪一种就更好一些。在这篇文章的大 部分示例代码中,我使用人们常说的K&R风格。如果你不喜欢K&R,那就用另一种风格好了。

注释


你可以有两种类型的注释放到你的Java代码中:Javadoc注释(也叫文档注释)和实现注释。Javadoc注释可以用javadoc工具提取并产生API文档。实现注释用来解释代码的“如何”和“为什么”。使用下面的原则来注释你的Java代码。


在任何允许使用Javadoc注释的地方使用Javadoc注释(最起码用在类和方法上)。
使用块注释而不是行尾(拖尾)注释,除了一些特殊情况,比如变量的声明。


而且,要记住好的注释总是有帮助的;而坏的注释却是令人讨厌的。


例1. 坏的注释风格。

  1.    // applyRotAscii() -- Apply ASCII ROT
  2.    private  void  applyRotAscii(){
  3.       try {
  4.          int  rotLength = Integer .parseInt(rotationLengthField.getText().trim()); // get rot len
  5.          RotAscii cipher = new  RotAscii(rotLength); // new cipher
  6.          textArea.setText(cipher.transform(textArea.getText())); // transform
  7.       }catch (Exception  ex){ 
  8.          /* Show exception */
  9.          ExceptionDialog.show(this "Invalid rotation length: " , ex); }
  10.    }




例2. 好的注释风格。

  1.    /**
  2.     * Apply the ASCII rotation cipher to the user's text. The length is retrieved
  3.     * from the rotation length field, and the user's text is retrieved from the
  4.     * text area.
  5.     *
  6.     * @author Thornton Rose
  7.     */
  8.    private  void  applyRotAscii() {
  9.       int       rotLength = 0;  // rotation length
  10.       RotAscii cipher = null ;  // ASCII rotation cipher
  11.    
  12.       try  {
  13.          // Get rotation length field and convert to integer.
  14.           
  15.          rotLength = Integer .parseInt(rotationLengthField.getText().trim());
  16.          
  17.          // Create ASCII rotation cipher and transform the user's text with it.
  18.           
  19.          cipher = new  RotAscii(rotLength);
  20.          textArea.setText(cipher.transform(textArea.getText()));
  21.    
  22.        } catch (Exception  ex) {
  23.          // Report the exception to the user.
  24.          
  25.          ExceptionDialog.show(this "Invalid rotation length: " , ex);
  26.       }
  27.    }



块和声明


使用下面的原则来写块和声明:
 
每行只放置一个声明。
控制声明的时候总是使用大括号(比如,'if')。
考虑在块结束的地方做注释(比如,} //end if),特别是那些长的或者嵌套的块。
把各种变量的声明放在块的开头。
总是初始化变量。
如果想做完美主义者,左对齐变量名。
switch块中缩进case子句。
操作符的前后分别加上空格。
使用if,for,或者while的时候,在"("前面加上空格。
在表达式中使用空格和圆括号以提高可阅读性。

'for'循环中的变量在应用“把各种变量的声明放在块的开头”的原则时是个例外。循环变量应该在for语句的初始化部分进行声明,比如,for(int i = 0; ...)


在块结束的地方放置一个声明有助于你捕捉到意外删除的结束大括号。有时候,在一个巨大的文件中要想找到它们真的会把你逼疯的。


例3. 坏的块风格。

  1.    try {
  2.       for (int  i=0;i<5;i++){
  3.          ...
  4.          }
  5.       int  threshold=calculateThreshold(); 
  6.       float  variance=(threshold*2.8)-1;
  7.       int  c=0;
  8.       if  (threshold<=15) c=calculateCoefficient();
  9.       switch (c){
  10.       case  1: setCeiling(c*2); break ;
  11.       case  2: setCeiling(c*3); break ;
  12.       else : freakOut();
  13.       }
  14.    }catch (Exception  ex){ ... }




例4. 好的块风格。

  1.    try  {
  2.       int    threshold  = 0;
  3.       float  variance    = 0.0;
  4.       int    coefficient = 0;
  5.       
  6.       // Prepare 5 cycles.
  7.       
  8.       for  (int  i = 0; i < 5; i ++){
  9.          prepareCycle(i);
  10.       }
  11.       
  12.       // Calculate the threshold and variance.
  13.       
  14.       threshold = calculateThreshold();
  15.       variance = (threshold * 2.8) - 1;
  16.       
  17.       // If the threshold is less than the maximum, calculate the coefficient.
  18.       // Otherwise, throw an exception.
  19.       
  20.       if  (threshold <= MAX_THRESHOLD) {
  21.          coefficient = calculateCoefficient();
  22.       } else  {
  23.          throw  new  RuntimeException ("Threshold exceeded!" );
  24.       }
  25.       
  26.       // Set the ceiling based on the coefficient.
  27.       
  28.       switch  (coefficient) {
  29.          case  1: 
  30.             setCeiling(coefficient * 2); 
  31.             break ;
  32.           
  33.          case  2: 
  34.             setCeiling(coefficient * 3); 
  35.             break ;
  36.           
  37.          else
  38.             freakOut();
  39.       } // end switch
  40.    } catch (Exception  ex) { 
  41.       ... 
  42.    } // end try

简介


这是这个两部分的关于Java编码风格系列的结论部分。在第一部分中,我介绍了我用良好的习惯来编写Java的一些情况,解释了为什么我们 应该关心我们代码的样子,并且展示了良好Java风格的一些基本要素。在这个部分,我会展示良好Java风格的更多要素,并把我的情况作一个总结。

源文件


有很多种方式来组织Java源文件。这是工作得很好的一个:

文件头注释(可选)。
包声明。
空行或其它分隔符。
导入声明。
空行或其它分隔符。
类。


例1. 坏的文件组织。

  1.    package  org.rotpad;
  2.    import  java.awt.*;
  3.    import  javax.swing.event.*;
  4.    import  org.javacogs.*;
  5.    import  javax.swing.*;
  6.    import  java.awt.event.*;
  7.    class  Foo {
  8.     ...
  9.    }
  10.    public  class  RotPad extends  JFrame  {
  11.     ...
  12.    }




例2. 好的文件组织。

  1.    package  org.rotpad;
  2.    
  3.    // Java classes
  4.    import  java.awt.*;
  5.    import  java.awt.event.*;
  6.    import  javax.swing.*;
  7.    import  javax.swing.event.*;
  8.    
  9.    // JavaCogs classes
  10.    import  org.javacogs.*;
  11.    
  12.    /**
  13.     * RotPad is a simple GUI application for performing rotation ciphers on plain 
  14.     * text.
  15.     *
  16.     * @author Thornton Rose
  17.     * @version 1.0
  18.     */
  19.    public  class  RotPad extends  JFrame  {
  20.       ...
  21.    }
  22.    
  23.    //-----------------------------------------------------------------------------
  24.    
  25.    /**
  26.     * Foo is ...
  27.     *
  28.     * @author Thornton Rose
  29.     * @version 1.0
  30.     */
  31.    class  Foo {
  32.       ...
  33.    }



导入声明


一个复杂的类可以有大量的导入,这些导入会变得不可控制,特别是如果你喜欢导入单个类而不是整个包(比如,java.awt.*)。为了能够处理这些导入,像下面这样来处理它们:

Java标准类(java.*)。
Java扩展类(javax.*)。
第三方类。
应用程序类。

一定要为第三方类和应用程序类作注释,特别是那些名字不容易让人辨认的类。使用行尾注释,或者在这一部分的开头放一个注释。同样,如果你真的想成为一个完美主义者,那么按照字母顺序为导入的每一组类进行排序。


例3. 坏的导入风格。

  1.    import  java.util.*;
  2.    import  javax.swing.*;
  3.    import  java.awt.event*;
  4.    import  com.gensym.com.*;
  5.    import  javax.swing.table.*;
  6.    import  com.pv.jfcx.*;
  7.    import  java.awt.*;
  8.    import  com.melthorn.util.*;




例4a. 好的导入风格。

  1.    import  java.awt.*;
  2.    import  java.awt.event*;
  3.    import  java.util.*;
  4.    import  javax.swing.table.*;
  5.    import  com.gensym.com.*;     // BeanXporter
  6.    import  com.pv.jfcx.*;        // ProtoView
  7.    import  com.melthorn.util.*;  // Utilities



例4b. 好的导入风格。

  1.    // Java classes
  2.    import  java.awt.*;
  3.    import  java.awt.event*;
  4.    import  java.util.*;
  5.    import  javax.swing.table.*;
  6.                            
  7.    // BeanXporter
  8.    import  com.gensym.com.*;     
  9.                            
  10.    // ProtoView GUI components
  11.    import  com.pv.jfcx.*;
  12.                            
  13.    // Application classes
  14.    import  com.melthorn.util.*;





组织Java源文件的时候如果不把类组织好,那么你同样得不到良好的风格。现在教你如何组织源文件里的类。


Javadoc注释或者其它头注释。
类声明。
域(Field)声明。
空行或其它分隔符。
构建器。
空行或其它分隔符。
方法,除了main(),有逻辑的聚合起来。
空行或其它分隔符。
内部类。
空行或其它分隔符。
main()。


例5. 坏的类风格。

  1.    // RotPad -- GUI app. for ROT ciphering
  2.    public  class  RotPad extends  JFrame  {
  3.    private  static  final  String  TRANSFORM_ROT13    = "ROT13" ;
  4.    private  static  final  String  TRANSFORM_ROT13N5  = "ROT13N5" ;
  5.    private  static  final  String  TRANSFORM_ROTASCII = "ROT-ASCII" ;
  6.    
  7.    private  void  jbInit() throws  Exception  {
  8.       ...
  9.    }
  10.    
  11.    public  static  final  String  TITLE   = "RotPad" ;
  12.    public  static  final  String  VERSION = "1.0" ;
  13.    
  14.    public  static  void  main(String [] args) {
  15.       ...
  16.    }
  17.    
  18.    public  RotPad() {
  19.       ...
  20.    }
  21.    
  22.    private  JPanel  jPanel1 = new  JPanel ();
  23.    private  JPanel  jPanel2 = new  JPanel ();
  24.    private  BorderLayout  borderLayout1 = new  BorderLayout ();
  25.    ...
  26.    }




例6. 好的类风格。

  1.    /**
  2.     * RotPad is a simple GUI application for performing rotation ciphers on plain 
  3.     * text.
  4.     *
  5.     * @author Thornton Rose
  6.     * @version 1.0
  7.     */
  8.    public  class  RotPad extends  JFrame  {
  9.       // Public constants
  10.        
  11.       public  static  final  String  TITLE   = "RotPad" ;
  12.       public  static  final  String  VERSION = "1.0" ;
  13.        
  14.       // Private constants
  15.       
  16.       private  static  final  String  TRANSFORM_ROT13    = "ROT13" ;
  17.       private  static  final  String  TRANSFORM_ROT13N5  = "ROT13N5" ;
  18.       private  static  final  String  TRANSFORM_ROTASCII = "ROT-ASCII" ;
  19.      
  20.       // GUI components [JBuilder generated]
  21.        
  22.       private  BorderLayout  borderLayout1 = new  BorderLayout ();
  23.       private  JPanel  jPanel1 = new  JPanel ();
  24.       private  JPanel  jPanel2 = new  JPanel ();
  25.       ...
  26.       
  27.       /**
  28.        * Construct a new instance of this class.
  29.        */
  30.       public  RotPad() {
  31.          ...
  32.       }
  33.       
  34.       /**
  35.        * Initialize UI components. [JBuilder generated]
  36.        */
  37.       private  void  jbInit() throws  Exception  {
  38.          ...
  39.       }
  40.        
  41.       ...
  42.       
  43.       //--------------------------------------------------------------------------
  44.      
  45.       /**
  46.        * Start the application.
  47.        */
  48.       public  static  void  main(String [] args) {
  49.          ...
  50.       }
  51.    }



域声明


一些类有大量的域,如果不组织好的话,维护起来是非常难的。像下面这样来组织它们:

public常量(final和static final)。
public变量。
protected常量
protected变量。
package常量。
package变量。
private常量。
private变量。


而且,写域声明的时候遵守下面的原则:

每行只写一个声明。
最起码,为public和protected域写Javadoc注释。
常量名用大写,因为大写使它们在声明和表达式中都更加显眼。
如果你使用能够产生域声明的工具,比如JBuilder或者Visual Cafe,要把自动产生的域和其它的域分开,这样维护UI代码的时候会容易一些。


例7. 坏的域风格。

  1.    public  class  CustomerSearchDialog extends  JDialog  {
  2.       private  JLabel  firstNameLabel = new  JLabel ();
  3.       private  JLabel  lastNameLabel = new  JLabel ();
  4.       public  static  final  RESULT_SELECT = 1;
  5.       private  Vector  results = new  Vector (); // Search results.
  6.       private  DefaultTableModel  tableModel = new  DefaultTableModel ();
  7.       public  static  final  RESULT_CANCEL = 0;
  8.       // ...
  9.    }




例8. 好的域风格。

  1.    /**
  2.     * ...
  3.     */
  4.    public  class  CustomerSearchDialog extends  JDialog  {
  5.       /**
  6.        * Indicates that search was cancelled; returned by showDialog() when
  7.        * user clicks cancel button.
  8.        */
  9.       public  static  final  RESULT_CANCEL = 0;
  10.       
  11.       /**
  12.        * Indicates that a customer was selected; returned by showDialog() when
  13.        * user clicks select button.
  14.        */
  15.       public  static  final  RESULT_SELECT = 1;
  16.       
  17.       private  Vector             results    = new  Vector ();             // Search results.
  18.       private  DefaultTableModel  tableModel = new  DefaultTableModel ();  // Grid model.
  19.       
  20.       // GUI fields. [JBuilder]
  21.       
  22.       private  JLabel  firstNameLabel = new  JLabel ();
  23.       private  JLabel  lastNameLabel = new  JLabel ();
  24.       // ...
  25.    }



方法声明


编写方法声明的时候遵守下面的原则:


总是要有Javadoc注释或其它头注释。
总是要把访问修饰符放在前面。
如果行太长,把它分为一行或多行。
如果方法参数过多,考虑每行只放一个。
不要在方法名和开圆括号("(")之间加入空格。
总是在闭圆括号(")")和开大括号("{")之间加入空格(它可以是一个分行符)。


例9. 坏的方法风格。

  1.    public  int  getTypeCount (String  custType)
  2.    {
  3.    ...
  4.    }
  5.    static  public  getInstance(){ ... };
  6.    public  void  showRange()
  7.       throws  RangeException {
  8.     ...
  9.    }




例10. 好的方法风格。

  1.    /**
  2.     * Return the single instance of this class.
  3.     */
  4.    public  static  CalculationEngine getInstance() {
  5.       return  instance;
  6.    }
  7.    
  8.    /**
  9.     * Calculate the consumption coefficient.
  10.     */
  11.    public  float  calculateConsumptionCoefficient(int  base, float  variance, 
  12.          int  iterations) throws  RangeException {
  13.       // ...
  14.    }
  15.   
  16.    /**
  17.     * Calculate the consumption coefficient.
  18.     */
  19.    public  float  calculateConsumptionCoefficient(
  20.          int  base, 
  21.          float  variance, 
  22.          int  iterations) 
  23.       throws  RangeException
  24.    {
  25.       // ...
  26.    }
  27.    
  28.    /**
  29.     * Calculate the consumption coefficient.
  30.     */
  31.    public  float  calculateConsumptionCoefficient(int  base, 
  32.                                                 float  variance, 
  33.                                                 int  iterations) 
  34.       throws  RangeException
  35.    {
  36.       // ...
  37.    }



结论


至于结论,在关于编码风格的主题上,我有一个最终的想法告诉你。无论你遵守怎样的原则,也无论你关于一些事情比如缩进风格(参 看, Raymond, "Indent Style")的信仰是如何强烈,你要记住的是当你编写代码的时候你总的目标应该是让代码在别人眼里看起来是可 以理解和可以维护的。 











分享到:
评论

相关推荐

    java 注释风格和java格式风格模版

    总结来说,Java注释风格和代码格式模板是良好编程实践的重要组成部分,它们有助于提高代码的可读性和团队间的协作效率。`codeformatter.xml`和`codetemplates.xml`文件提供了定制和共享这些规范的途径,使得开发者...

    Java编程风格(The Elements of Java Style)

    在软件工程领域,良好的编程风格对于创建高质量、可维护的代码至关重要。《Java编程风格》(The Elements of Java Style)旨在为Java开发者提供一套实用的指导原则,帮助他们编写出不仅功能完善而且风格统一、易于...

    Java编程风格

    Java编程风格是编程界的一本经典著作,它深入探讨了如何编写出清晰、高效且易于维护...以上只是部分Java编程风格的知识点,实际的书籍中会有更详细的讲解和实例,帮助开发者形成良好的编程习惯,写出高质量的Java代码。

    Java swing风格美化

    "Java Swing风格美化"是针对这一问题,通过引入第三方库来改变Swing程序的视觉样式,使其看起来更加现代化和吸引人。本主题将深入探讨如何使用这些皮肤包来提升Swing程序的美学效果。 首先,我们来看看描述中提到的...

    Google Java编程风格指南

    Google的这套风格指南不仅关注代码的美观性,更重要的是提倡良好的编程习惯和一致性,这将极大地提高团队协作效率和代码质量。因此,无论是个人项目还是团队开发,理解和应用这些规则都是非常有益的。

    java风格

    【Java风格】编程指南 Java语言以其严谨的语法、面向对象的设计和强大的跨平台能力,深受全球开发者的喜爱。在编程实践中,遵循一定的"Java风格"可以提高代码的可读性、可维护性和团队协作效率。本文将深入探讨Java...

    《Java编程风格》翻译版.pdf

    《Java编程风格》是一本关于Java编程过程中应当遵循的一系列编码规范的指南书籍。该书不仅提供了具体编码风格的建议,还强调了编写高质量代码的重要性。编码规范对于确保代码的一致性和可读性至关重要,它能够帮助...

    原创java写的画图板软件(代码风格良好)

    良好的代码风格体现在模块化和设计模式的应用上。在这个项目中,可能会使用观察者模式来处理事件,单例模式来管理全局资源,工厂模式来创建组件等。代码的结构清晰,职责分明,易于维护和扩展。 通过这个简单的...

    编码规范 注释规范 代码风格 JAVA

    总结来说,理解和遵循编码规范、注释规范以及代码风格对于任何Java开发者都是至关重要的。华为的这些资源提供了一套完整的框架,旨在帮助开发团队产出高质量、易维护的代码。通过深入学习和应用这些规范,开发者不仅...

    pragmatic-java-engineer,Java Java.zip

    - **代码规范**:遵循良好的编程习惯,如命名规范、注释编写,以及如何编写可读性强、易于维护的代码。 - **性能优化**:通过合理的数据结构选择、算法优化、内存管理等方式提高程序性能。 - **错误处理**:如何...

    Java编程风格及基础类库使用培训

    Java编程风格及基础类库使用培训是针对初学者和有一定经验的开发者进行的一次深入学习活动,由知名学府清华大学提供。这份培训资料主要涵盖了Java编程语言的基本规范、最佳实践以及核心类库的使用方法。在Java编程...

    Google Java编程风格指南1

    良好的导入风格要求只导入需要的类,并避免使用通配符导入(如`import java.util.*`),以减少命名冲突和提高代码可读性。 **3.4 类声明** 类声明紧随`import`语句之后,每个类应独立声明,并按照它们在包内的逻辑...

    java语言GUI程序皮肤包

    在Java中,我们可以利用各种库和工具来实现GUI的皮肤化,其中就包括Office风格和Mac风格的皮肤。 Java GUI皮肤的设计通常基于组件库,如Java Swing或JavaFX。这些库提供了许多预定义的组件,如按钮、文本框、菜单等...

    风格提交—java技术

    风格提交—Java技术 在Java开发中,"风格"通常指的是编程规范、代码风格和最佳实践,这些都是确保代码可读性...在实际项目中,开发者应当养成良好的编程习惯,不断提升自己的编程素养,以实现高效、高质量的Java编程。

    [ppt]Java编程风格及基础类库使用(free)

    在Java编程中,良好的编程风格是代码可读性和维护性的关键。遵循一定的编程规范不仅可以提升团队合作效率,也能减少因代码不清晰导致的错误。清华大学的这份PPT详细介绍了Java编程风格,旨在帮助初学者建立良好的...

    C2风格的框架程序

    良好的文档和代码注释是确保系统可维护性的关键。 总之,C2风格的框架程序通过组件和连接件的组合,提供了一种高效、灵活的软件设计方式。在Java环境中实现,结合异步消息通信,可以构建出高性能、模块化的大型应用...

    Java编程风格指导.pdf

    总的来说,良好的Java编程风格涉及到命名规范、代码格式化和有效的注释。通过遵循这些指导原则,开发者可以创建出更加清晰、易于理解和维护的代码,从而提高软件工程的整体效率。在团队开发中,统一的编程风格还可以...

Global site tag (gtag.js) - Google Analytics