SlideShare une entreprise Scribd logo
1  sur  61
Code
Quality, Maintainability, Reusability, Debuggi
                 ng, Testing
                 Nguyen Trung Thanh




                     LOGO
                                           1
Outline

 Code Quality & Standards.
 Debugging, logging etc.
 Testing.




                              2
Key Principles; Coding

 Understandability
 Coding Convention
 High cohesion
 Loose coupling
 Code Formatting
 Consistent Naming
 Information hiding
 Valuable Comments

                                3
Code Standards

   Why?
    – Gives less defects.
    – Easier/cheaper maintenance.
    – Several people may work on and understand the
      same code.
    – Code to be read, not only written.
   Java coding standards:
    – The Elements of Java Style; Vermeulen et.al. SIGS
      Books.
    – http://java.sun.com/docs/codeconv/html/CodeConvTO
      C.doc.html.


                                                          4
Code Standards

   General rules:
    – Simplicity – Build simple classes and
      methods. Keep it as simple as possible, but not
      simpler (Einstein).
    – Clarity – Ensure item has a clear purpose.
      Explain where, when, why, and how to use
      each.
    – Completeness – Create complete
      documentation; document all features and
      functionality.
                                                    5
Code Standards

   General rules (continued):
    – Consistency – Similar entities should look and
      behave the same; dissimilar entities should
      look and behave differently. Create and apply
      standards whenever possible.
    – Robustness – Provide predictable
      documented behaviour in response to errors
      and exceptions. Do not hide errors and do not
      force clients to detect errors.



                                                      6
Code Standards

 Do it right the first time !
 Your professionalism is expressed by
  applying code standards !
 Document any deviations!




                                         7
Formatting

 Is important for readability, not for the
  compiler.
 Use a common standard for code
  formatting.
 Do not alter the style of old code to fit new
  standards.




                                                  8
Examples (1)

class MyClass {
  void function (int arg) {
    if (arg < 0) {
       for (int index = 0; index <= arg; index++) {
          //… Some Action Code …
       } // end for
    } // end if
  } // end function
} // end MyClass




                                                      9
Examples (2)

   Include white space:
    – Bad: double length=Math.sqrt(x*x+y*y);
    – Better: double length = Math.sqrt(x * x + y * y);
    – Use blank lines to separate.
    – Do not use hard tabs.




                                                     10
Naming

   Clear, unambiguous, readable,
    meaningful. Describe the purpose of the
    item:
    – Bad: X1, X2, mth, get, tmp, temp, result.
    – Give a descriptive name to temporary
      variables.
   But: scientific formulas may be better
    formulated with single characters/words
    representing symbols instead of descriptive
    names.
                                                  11
Naming

 Establish and use a common naming convention.
 Problems creating a good name  purpose of the
  operation is not clear.
    – Bad: void get(…)., better: retrieveDataSamples.
    – Bad: Time day(Time p_day), better: getDate or
      getTruncDate.
    – Bad: void result(…), better: createResults.
    – Bad: void gas/oil/water, better: calculate…VolumeRate.




                                                          12
Java Naming Convention

 Package: scope.mypackage
 Classes: MyClass
 Methods: myMethod
 Constants: MY_CONSTANT
 Attribute: myAttribute
 Variable: myVariable




                              13
Parameters
   Actual parameters should match the formal
   Input-modify-output order
   If several operations use similar parameters, put
    the similar parameters in a consistent order
   Use all parameters
   Document interface assumptions about
    parameters
     access type, unit, ranges, non-valid values
   Limit the number of parameters to about seven


                                                    14
Comments; Why, when, where, what
 Why: To be able to find out what a operation
  does after a half, one or two years. Automatic
  API documentation.
 When; Document your code before or when you
  write it; Design before you implement. Put the
  design in the operation.
 Where; Before the operation, at specific
  formulas, decision points etc.
 What; Document the algorithm, avoid
  unnecessary comments. Refer to a specification
  if existing.


                                               15
Project Organisation:Spider-web
                                                                                                                          ::pck_stream




                                                                                                                                                                                               ::lift_account
                                         ::pck_stock




                                                                                                                                                                                                                                     ::theoretical




                           ::pck_check



                                                                                                                                                                                                                                                                   ::puf




    ::pck_facility




                                                                                              ::pck_flowline




                                                                                                                                                                                                                                                               ::sep_test




                                                                                                                                                                                                                                                                                                     ::pck_regression




                                                                                                                                                                                                                                                                            ::pck_cargo




                                                                           ::transfer_basis

                                                                                                                                           ::summarise
              ::pck_well




                                                                                                                                                                                                                                                                                          ::pck_cargo_doc




           ::well_node
                                            ::pck_stream_network   ::pck_system
                                                                                                                                                                             ::lagkodeserver                    ::comp_analysis   ::choke
                                                                                                           ::regularity                                                                                                                                                                        ::calc_stream
                                                                                                                                                 ::mathlib




                                                                                                                                                                                                                                                     ::units




                                                                                                                          ::value_adjust
                                                                                                                                                             ::tbp_product




                                                                                                                                                                                                                                                                                                                        16
Architecture; How to Avoid Spider-web
   Class/package organisation (loose
    coupling, high cohesion):
    -Split classes in (package/service) layers
    (user, data and business). Use package
    scoping (no.ntnu.idi…..).
    -Uni-directional dependencies.




                                                 17
Refactor to a New Architecture

   ::EcBpStreamShipper    ::EcBpStreamFlare   ::EcBpStreamFluid                         ::EcDpWellStream




                                                 ::EcBpStream
                                                                                     ::EcDpDerivedStream               ::comp_analysis




::Theoretical            ::EcDpStream               ::EcDpWellReservoir   ::EcDpStreamFluid                ::calc_stream




                                                                                                                                         18
Information Hiding
 Hide the action part in control structures
  (functional cohesion) if complex, else delegate
  to a method.
 What to hide:
     Areas that are likely to change; hardware
      dependencies, input/output, non-standard language
      features, difficult design and implementation
      areas, data-size constraints, business rules, potential
      changes.
     Complex data.
     Complex logic.


                                                            19
Binding

   Bind constants as late as possible
    – Do not use magic Numbers, avoid hard-coded values
      totalFooDay = totalFooHour * 24;
      if (me.equals(”thirsty”)) return ”water”;
    – Avoid global variables (constants OK)
    – Use separate classes/methods to hide hard-coded
      values
          Achieves faster maintenance, and avoids copy-paste errors
          Makes code better suited for reuse
          Static methods and/or constants
MyConstants.C1_SPECIFIC_GRAVITY

                                                                       20
Java Exceptions

 Unchecked run-time exception: serious
  unexpected errors that may indicate an
  error in the program’s logic Termination.
 Checked exception: errors that may
  occur, however rarely, under normal
  program operation      The caller must catch
  this exception.



                                            21
Java Exceptions

 Only convert exceptions to add
  information. If the method does not know
  how to handle an exception it should not be
  handled.
 Do not silently absorb a run-time or
  error exception      makes code very hard
  to debug.
 Use finally blocks to release resources.


                                           22
Code Defensively

   Check input data for validity (Pre-conditions).
    – Range, comment assumptions about acceptable input
      ranges in the code.
    – Use a general approach for error handling when
      erroneous data.
 Use exception handling only to draw attention to
  unexpected cases (Do NOT perform any
  processing in exception code) (invariants).
 Anticipate changes; Hide to minimise impact of
  change.


                                                       23
Code Defensively

 Introduce debugging aids early (logging).
 Check function return values (post-
  conditions).
 Return friendly error messages; Write to a
  log file any system specific error messages
  (IO/SQL Exceptions, error codes etc.).




                                            24
Summary

 Remember your code should be
  understandable.
 Maintenance is often up to 70% of a total
  project cost.
 Use quality control.




                                              25
Outline

 Code quality and Code Standards.
 Debugging, logging etc.
 Testing.




                                     26
Debugging

   Single thread/process.
    – IDE’s with debugger most often sufficient.
   Multiple clients, threads, distributed applications.
    – Synchronisation issues to protect the state of objects.
    – IDE’s (most often) lack good support.
    – Pre-instrumentation of code is often necessary.
   Non-visual services (e.g. Real-time data
    conversions).
    – May debug single runs in IDE’s.
    – Hard to debug in real settings: system runs
      continuously or discretely at fixed times

                                                                27
Application Logging: What and Why?

 An application log is a text history of notable
  events logged by your application.
 The logs helps you to figure out what went wrong
  (and right) during the execution of your
  application.
 With the advent of N-tier architectures, Servlets,
  JSPs, and EJBs, application logging is particularly
  important to report errors that cannot or should
  not be surfaced to the user interface.


                                                   28
System Event Categories

   Levels:
    – CRITICAL_ERROR. (Highest - 1)
    – ERROR.
    – WARNING.
    – INFORMATION.
    – DETAIL.
    – TRACE. (Lowest - 6)




                                      29
Logging Granularity

 The greater the granularity, the deeper the
  level of detail.
 Agreed and documented set of event
  categories       determine the granularity to
  log those events.
 Separate logs for e.g.
    – thread pool.
    – SQL processor.


                                                  30
Logging Events

   Instrument code with logging statements:
    – AppLog.criticalError("Caught unexpected
      exception: " + e);
    – SQLLog.info("Executing SQL query: " +
      statement);
    – AppLog.trace("Entering method getName()");
   Notice: the code does not need to have
    any "if" logic.


                                                   31
Configuring the Logs

   Configuration from a properties file.
    LogFileExtension = log
    LogFilePath = c:temp
    LoggingLevel = 2
    LoggingMechanism = log.StandardErrLoggingMechanism
    LogFieldSeparator = |




                                                    32
Configuring the Logs

 You may select the output logging level.
  Default is the INFO level.
 All events logged at a level less than or
  equal to the log's current logging level will
  be output to the logging mechanisms.
 Events logged at a numerically higher level
  (i.e., a less critical level) will be discarded.



                                                 33
Configuring the Logs

 At runtime, you can increase or decrease
  the logging level of any of your logs without
  affecting your other logs.
 If you are trying to debug a nasty problem
  with your thread pool, you can
  programmatically change the log at runtime
  :
ThreadLog.getInstance().setLoggingLevel(Log.TRACE_LEVEL);




                                                            34
Configuring the Logs

   Other ways to dynamically reset the logging level
    at runtime:
    – In a debugger, you can change the value of the log's
      currentLoggingLevel variable.
    – In an application server, you can examine and
      manipulate log properties with some JSPs.
    – Use RMI to manipulate the log properties of a remote
      JVM.
    – There are more options you can configure both
      programmatically and via a properties file.


                                                             35
Reading the Logs

   Sample entries from a shared log, a vertical
    bar ( | ), is used to delimit the various fields
    of log entries:
RequestLog|L4|09:32:23:769|ExecuteThread-5|Executing
  request number 4
SQLLog|L4|09:32:23:835|ExecuteThread-5|select * from
  Customer where id = 35.
RequestLog|L4|09:32:23:969|ExecuteThread-5|Request 4
  took 200 milliseconds.




                                                       36
Reading the Logs
   Import the log into a spreadsheet:
    – ASCII text import with a vertical bar as a field
      delimiter.
    – Sort or filter the log using various
      spreadsheet capabilities.




                                                     37
Outline

 Code quality and Code Standards.
 Debugging, logging etc.
 Testing.




                                     38
Testing

 Not closely integrated with development
  prevents measurement of the progress of
  development - can't tell when something starts
  working or when something stops working.
 JUnit to cheaply and incrementally build a test
  suite that helps to:
    – measure your progress,
    – spot unintended side effects.
    – focus your development efforts.



                                                    39
JUnit

   Automatic testing framework.
    – Acceptance tests.
    – Integration test.
    – Unit test.
 Reports the number of defects graphically.
 May create many tests for each method.




                                               40
JUnit Example

   Pay attention to the interplay of the code
    and the tests.
    – The style: to write a few lines of code, then a
      test that should run,
    – or even better: to write a test that won't run,
      then write the code that will make it run.
   The program presented solves the problem
    of representing arithmetic with multiple
    currencies.


                                                        41
Example: Money
class Money {
  private int fAmount;
  private String fCurrency;
  public Money(int amount, String currency) {
    fAmount= amount
    fCurrency= currency;
  }
  public int amount() {
      return fAmount;
  }
  public String currency() {
    return fCurrency;
  }
}


                                                42
JUnit

 JUnit defines how to structure your test
  cases and provides the tools to run them.
 You implement a test in a subclass of
  TestCase.




                                              43
Example: Money

public Money add(Money m) {
  return new Money(amount()+m.amount(), currency());
}




                                                  44
Junit
 Define MoneyTest as a subclass of
  TestCase.
 Put MoneyTest in the same package as the
  classes under test  access to the
  package private methods.
    – Add method testSimpleAdd, that will exercise
      the simple version of Money.add() above.
    – A JUnit test method is an ordinary method
      without any parameters.

                                                  45
Example: MoneyTest
public class MoneyTest extends TestCase {
 //…
  public void testSimpleAdd() {
      Money m12JPY= new Money(12, “JPY"); // (1)
      Money m14JPY= new Money(14, “JPY");
      Money expected= new Money(26, “JPY");
      Money result= m12JPY.add(m14JPY);    // (2)
      assert(expected.equals(result));     // (3)
  }
}




                                                    46
Developing Tests
public void testEquals() {
  Money m12CHF= new Money(12, "CHF");
  Money m14CHF= new Money(14, "CHF");
  assert(!m12CHF.equals(null));
  assertEquals(m12CHF, m12CHF);
  assertEquals(m12CHF, new Money(12, "CHF")); // (1)
  assert(!m12CHF.equals(m14CHF));
}




                                                       47
Developing Tests
public boolean equals(Object anObject) {
  if (anObject instanceof Money) {
    Money aMoney= (Money)anObject;
    return aMoney.currency().equals(currency())
            && amount() == aMoney.amount();
  }
  return false;
}
   Override the method hashCode whenever you override
    method equals.




                                                         48
Assertions
   Verification in JUnit by calling assert which is
    inherited from TestCase.
    – Assert triggers a failure that is logged by JUnit
      when the argument isn't true.
    – Since assertions for equality are very
      common, TestCase defines an assertEquals
      convenience method. Logs the printed value of
      the two objects if they differ.
    – Shows why a test failed in a JUnit test result
      report. Logged as a string representation
      created by toString.
                                                      49
Test Fixture
public class MoneyTest extends TestCase {
  private Money f12CHF;
  private Money f14CHF;
  protected void setUp() {
     f12CHF= new Money(12, "CHF");
     f14CHF= new Money(14, "CHF");
  }
}




                                            50
Tests Refactored
public void testEquals() {
  assert(!f12CHF.equals(null));
  assertEquals(f12CHF, f12CHF);
  assertEquals(f12CHF, new Money(12, "CHF"));
   assert(!f12CHF.equals(f14CHF));
}
public void testSimpleAdd() {
  Money expected= new Money(26, "CHF");
  Money result= f12CHF.add(f14CHF);
  assert(expected.equals(result));
}




                                                51
Running of Tests

   Two additional steps are needed to run the
    two test cases:
    1. define how to run an individual test case,
    2. define how to run a test suite.
   JUnit supports two ways of running single
    tests:
    – static.
    – dynamic.


                                                    52
Test Case: Static
   Overrides the runTest method inherited from
    TestCase and call the desired test case.
    – Convenient way: anonymous inner class.
    – Note: each test must be given a name to identify it if it
      fails.
       TestCase test = new MoneyTest("simple add") {
          public void runTest() {
             testSimpleAdd();
          }
       };
    – A template method in the super-class will make sure
      runTest is executed when the time comes.
   Dynamic: TestCase  test = new
    MoneyTest("testSimpleAdd");
                                                              53
Test Suite: Dynamic

   Illustration of the creation of a test suite with
    the dynamic way to run a test:
    – You only pass the class with the tests to a
      TestSuite and it extracts the test methods
      automatically.

    public static Test suite() {
       return new TestSuite(MoneyTest.class);
    }



                                                    54
Test Suite: Static
public static Test suite() {
  TestSuite suite= new TestSuite();
  suite.addTest(new MoneyTest("money equals"){
                   protected void runTest() {
                      testEquals();
                   }
                }
  );
  suite.addTest(new MoneyTest("simple add") {
                  protected void runTest() {
                      testSimpleAdd();
                  }
               }
   );
   return suite;
}


                                                 55
JUnit Review

 In general: development will go much
  smoother writing tests a little at a time when
  developing.
 When coding the imagination of how the
  code will work. Capture the thoughts in a
  test.
 Test code is just like model code in working
     best if it is factored well.

                                              56
JUnit Review

 Keeping old tests running is just as
  important as making new ones run.
 The ideal is to always run all of your tests.
 When you are struck by an idea, defer
  thinking about the implementation. First
  write the test. Then run it. Then work on the
  implementation.



                                             57
Testing Practices
 Martin Fowler: "Whenever you are tempted
  to type something into a print statement or
  a debugger expression, write it as a test
  instead.”
 Only a fraction of the tests are actually
  useful.
    – Write tests that fail even though they should
      work, or tests that succeed even though they
      should fail.
    – Think of it is in cost/benefit terms. You want
      tests that pay you back with information.
                                                       58
Testing Practices

   Receive a reasonable return on your testing
    investment:
    – During Development.
    – During Debugging.
   Caution:
    – Once you get them running, make sure they stay
      running.
   Ideally, run every test in the suite every time you
    change a method. Practically, the suite will soon
    grow too large to run all the time.


                                                          59
Testing Practices

 Try to optimise your set-up code so you can run
  all the tests.
 Or,
    – create special suites that contain all the tests that might
      possibly be affected by your current development.
    – run the suite every time you compile.
    – make sure you run every test at least once a day:
      overnight, during lunch, during one of those long
      meetings….



                                                              60
Q&A


      61

Contenu connexe

Similaire à Coding convention

C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
Jason Hearne-McGuiness
 
Gae icc fall2011
Gae icc fall2011Gae icc fall2011
Gae icc fall2011
Juan Gomez
 

Similaire à Coding convention (20)

Checking the Cross-Platform Framework Cocos2d-x
Checking the Cross-Platform Framework Cocos2d-xChecking the Cross-Platform Framework Cocos2d-x
Checking the Cross-Platform Framework Cocos2d-x
 
Linux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLiteLinux version of PVS-Studio couldn't help checking CodeLite
Linux version of PVS-Studio couldn't help checking CodeLite
 
Solid and Infrastructure as Code
Solid and Infrastructure as CodeSolid and Infrastructure as Code
Solid and Infrastructure as Code
 
10 things i wish i'd known before using spark in production
10 things i wish i'd known before using spark in production10 things i wish i'd known before using spark in production
10 things i wish i'd known before using spark in production
 
Python Load Testing - Pygotham 2012
Python Load Testing - Pygotham 2012Python Load Testing - Pygotham 2012
Python Load Testing - Pygotham 2012
 
Testing Persistent Storage Performance in Kubernetes with Sherlock
Testing Persistent Storage Performance in Kubernetes with SherlockTesting Persistent Storage Performance in Kubernetes with Sherlock
Testing Persistent Storage Performance in Kubernetes with Sherlock
 
Picking Mushrooms after Cppcheck
Picking Mushrooms after CppcheckPicking Mushrooms after Cppcheck
Picking Mushrooms after Cppcheck
 
msc_pyparser - ModSecurity config parser presentation @CRS Community Summit i...
msc_pyparser - ModSecurity config parser presentation @CRS Community Summit i...msc_pyparser - ModSecurity config parser presentation @CRS Community Summit i...
msc_pyparser - ModSecurity config parser presentation @CRS Community Summit i...
 
2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop2011-02-03 LA RubyConf Rails3 TDD Workshop
2011-02-03 LA RubyConf Rails3 TDD Workshop
 
A Domain-Specific Embedded Language for Programming Parallel Architectures.
A Domain-Specific Embedded Language for Programming Parallel Architectures.A Domain-Specific Embedded Language for Programming Parallel Architectures.
A Domain-Specific Embedded Language for Programming Parallel Architectures.
 
[grcpp] Refactoring for testability c++
[grcpp] Refactoring for testability c++[grcpp] Refactoring for testability c++
[grcpp] Refactoring for testability c++
 
Create ReactJS Component & publish as npm package
Create ReactJS Component & publish as npm packageCreate ReactJS Component & publish as npm package
Create ReactJS Component & publish as npm package
 
Adam Margolin & Nicole DeFlaux Science Online London 2011-09-01
Adam Margolin & Nicole DeFlaux Science Online London 2011-09-01Adam Margolin & Nicole DeFlaux Science Online London 2011-09-01
Adam Margolin & Nicole DeFlaux Science Online London 2011-09-01
 
Linux Kernel, tested by the Linux-version of PVS-Studio
Linux Kernel, tested by the Linux-version of PVS-StudioLinux Kernel, tested by the Linux-version of PVS-Studio
Linux Kernel, tested by the Linux-version of PVS-Studio
 
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
C++ Data-flow Parallelism sounds great! But how practical is it? Let’s see ho...
 
Gae icc fall2011
Gae icc fall2011Gae icc fall2011
Gae icc fall2011
 
Typesafe spark- Zalando meetup
Typesafe spark- Zalando meetupTypesafe spark- Zalando meetup
Typesafe spark- Zalando meetup
 
Caching and tuning fun for high scalability @ 4Developers
Caching and tuning fun for high scalability @ 4DevelopersCaching and tuning fun for high scalability @ 4Developers
Caching and tuning fun for high scalability @ 4Developers
 
BUD17-300: Journey of a packet
BUD17-300: Journey of a packetBUD17-300: Journey of a packet
BUD17-300: Journey of a packet
 
New Directions for Mahout
New Directions for MahoutNew Directions for Mahout
New Directions for Mahout
 

Coding convention

  • 1. Code Quality, Maintainability, Reusability, Debuggi ng, Testing Nguyen Trung Thanh LOGO 1
  • 2. Outline  Code Quality & Standards.  Debugging, logging etc.  Testing. 2
  • 3. Key Principles; Coding  Understandability  Coding Convention  High cohesion  Loose coupling  Code Formatting  Consistent Naming  Information hiding  Valuable Comments 3
  • 4. Code Standards  Why? – Gives less defects. – Easier/cheaper maintenance. – Several people may work on and understand the same code. – Code to be read, not only written.  Java coding standards: – The Elements of Java Style; Vermeulen et.al. SIGS Books. – http://java.sun.com/docs/codeconv/html/CodeConvTO C.doc.html. 4
  • 5. Code Standards  General rules: – Simplicity – Build simple classes and methods. Keep it as simple as possible, but not simpler (Einstein). – Clarity – Ensure item has a clear purpose. Explain where, when, why, and how to use each. – Completeness – Create complete documentation; document all features and functionality. 5
  • 6. Code Standards  General rules (continued): – Consistency – Similar entities should look and behave the same; dissimilar entities should look and behave differently. Create and apply standards whenever possible. – Robustness – Provide predictable documented behaviour in response to errors and exceptions. Do not hide errors and do not force clients to detect errors. 6
  • 7. Code Standards  Do it right the first time !  Your professionalism is expressed by applying code standards !  Document any deviations! 7
  • 8. Formatting  Is important for readability, not for the compiler.  Use a common standard for code formatting.  Do not alter the style of old code to fit new standards. 8
  • 9. Examples (1) class MyClass { void function (int arg) { if (arg < 0) { for (int index = 0; index <= arg; index++) { //… Some Action Code … } // end for } // end if } // end function } // end MyClass 9
  • 10. Examples (2)  Include white space: – Bad: double length=Math.sqrt(x*x+y*y); – Better: double length = Math.sqrt(x * x + y * y); – Use blank lines to separate. – Do not use hard tabs. 10
  • 11. Naming  Clear, unambiguous, readable, meaningful. Describe the purpose of the item: – Bad: X1, X2, mth, get, tmp, temp, result. – Give a descriptive name to temporary variables.  But: scientific formulas may be better formulated with single characters/words representing symbols instead of descriptive names. 11
  • 12. Naming  Establish and use a common naming convention.  Problems creating a good name purpose of the operation is not clear. – Bad: void get(…)., better: retrieveDataSamples. – Bad: Time day(Time p_day), better: getDate or getTruncDate. – Bad: void result(…), better: createResults. – Bad: void gas/oil/water, better: calculate…VolumeRate. 12
  • 13. Java Naming Convention  Package: scope.mypackage  Classes: MyClass  Methods: myMethod  Constants: MY_CONSTANT  Attribute: myAttribute  Variable: myVariable 13
  • 14. Parameters  Actual parameters should match the formal  Input-modify-output order  If several operations use similar parameters, put the similar parameters in a consistent order  Use all parameters  Document interface assumptions about parameters  access type, unit, ranges, non-valid values  Limit the number of parameters to about seven 14
  • 15. Comments; Why, when, where, what  Why: To be able to find out what a operation does after a half, one or two years. Automatic API documentation.  When; Document your code before or when you write it; Design before you implement. Put the design in the operation.  Where; Before the operation, at specific formulas, decision points etc.  What; Document the algorithm, avoid unnecessary comments. Refer to a specification if existing. 15
  • 16. Project Organisation:Spider-web ::pck_stream ::lift_account ::pck_stock ::theoretical ::pck_check ::puf ::pck_facility ::pck_flowline ::sep_test ::pck_regression ::pck_cargo ::transfer_basis ::summarise ::pck_well ::pck_cargo_doc ::well_node ::pck_stream_network ::pck_system ::lagkodeserver ::comp_analysis ::choke ::regularity ::calc_stream ::mathlib ::units ::value_adjust ::tbp_product 16
  • 17. Architecture; How to Avoid Spider-web  Class/package organisation (loose coupling, high cohesion): -Split classes in (package/service) layers (user, data and business). Use package scoping (no.ntnu.idi…..). -Uni-directional dependencies. 17
  • 18. Refactor to a New Architecture ::EcBpStreamShipper ::EcBpStreamFlare ::EcBpStreamFluid ::EcDpWellStream ::EcBpStream ::EcDpDerivedStream ::comp_analysis ::Theoretical ::EcDpStream ::EcDpWellReservoir ::EcDpStreamFluid ::calc_stream 18
  • 19. Information Hiding  Hide the action part in control structures (functional cohesion) if complex, else delegate to a method.  What to hide:  Areas that are likely to change; hardware dependencies, input/output, non-standard language features, difficult design and implementation areas, data-size constraints, business rules, potential changes.  Complex data.  Complex logic. 19
  • 20. Binding  Bind constants as late as possible – Do not use magic Numbers, avoid hard-coded values totalFooDay = totalFooHour * 24; if (me.equals(”thirsty”)) return ”water”; – Avoid global variables (constants OK) – Use separate classes/methods to hide hard-coded values  Achieves faster maintenance, and avoids copy-paste errors  Makes code better suited for reuse  Static methods and/or constants MyConstants.C1_SPECIFIC_GRAVITY 20
  • 21. Java Exceptions  Unchecked run-time exception: serious unexpected errors that may indicate an error in the program’s logic Termination.  Checked exception: errors that may occur, however rarely, under normal program operation The caller must catch this exception. 21
  • 22. Java Exceptions  Only convert exceptions to add information. If the method does not know how to handle an exception it should not be handled.  Do not silently absorb a run-time or error exception makes code very hard to debug.  Use finally blocks to release resources. 22
  • 23. Code Defensively  Check input data for validity (Pre-conditions). – Range, comment assumptions about acceptable input ranges in the code. – Use a general approach for error handling when erroneous data.  Use exception handling only to draw attention to unexpected cases (Do NOT perform any processing in exception code) (invariants).  Anticipate changes; Hide to minimise impact of change. 23
  • 24. Code Defensively  Introduce debugging aids early (logging).  Check function return values (post- conditions).  Return friendly error messages; Write to a log file any system specific error messages (IO/SQL Exceptions, error codes etc.). 24
  • 25. Summary  Remember your code should be understandable.  Maintenance is often up to 70% of a total project cost.  Use quality control. 25
  • 26. Outline  Code quality and Code Standards.  Debugging, logging etc.  Testing. 26
  • 27. Debugging  Single thread/process. – IDE’s with debugger most often sufficient.  Multiple clients, threads, distributed applications. – Synchronisation issues to protect the state of objects. – IDE’s (most often) lack good support. – Pre-instrumentation of code is often necessary.  Non-visual services (e.g. Real-time data conversions). – May debug single runs in IDE’s. – Hard to debug in real settings: system runs continuously or discretely at fixed times 27
  • 28. Application Logging: What and Why?  An application log is a text history of notable events logged by your application.  The logs helps you to figure out what went wrong (and right) during the execution of your application.  With the advent of N-tier architectures, Servlets, JSPs, and EJBs, application logging is particularly important to report errors that cannot or should not be surfaced to the user interface. 28
  • 29. System Event Categories  Levels: – CRITICAL_ERROR. (Highest - 1) – ERROR. – WARNING. – INFORMATION. – DETAIL. – TRACE. (Lowest - 6) 29
  • 30. Logging Granularity  The greater the granularity, the deeper the level of detail.  Agreed and documented set of event categories determine the granularity to log those events.  Separate logs for e.g. – thread pool. – SQL processor. 30
  • 31. Logging Events  Instrument code with logging statements: – AppLog.criticalError("Caught unexpected exception: " + e); – SQLLog.info("Executing SQL query: " + statement); – AppLog.trace("Entering method getName()");  Notice: the code does not need to have any "if" logic. 31
  • 32. Configuring the Logs  Configuration from a properties file. LogFileExtension = log LogFilePath = c:temp LoggingLevel = 2 LoggingMechanism = log.StandardErrLoggingMechanism LogFieldSeparator = | 32
  • 33. Configuring the Logs  You may select the output logging level. Default is the INFO level.  All events logged at a level less than or equal to the log's current logging level will be output to the logging mechanisms.  Events logged at a numerically higher level (i.e., a less critical level) will be discarded. 33
  • 34. Configuring the Logs  At runtime, you can increase or decrease the logging level of any of your logs without affecting your other logs.  If you are trying to debug a nasty problem with your thread pool, you can programmatically change the log at runtime : ThreadLog.getInstance().setLoggingLevel(Log.TRACE_LEVEL); 34
  • 35. Configuring the Logs  Other ways to dynamically reset the logging level at runtime: – In a debugger, you can change the value of the log's currentLoggingLevel variable. – In an application server, you can examine and manipulate log properties with some JSPs. – Use RMI to manipulate the log properties of a remote JVM. – There are more options you can configure both programmatically and via a properties file. 35
  • 36. Reading the Logs  Sample entries from a shared log, a vertical bar ( | ), is used to delimit the various fields of log entries: RequestLog|L4|09:32:23:769|ExecuteThread-5|Executing request number 4 SQLLog|L4|09:32:23:835|ExecuteThread-5|select * from Customer where id = 35. RequestLog|L4|09:32:23:969|ExecuteThread-5|Request 4 took 200 milliseconds. 36
  • 37. Reading the Logs  Import the log into a spreadsheet: – ASCII text import with a vertical bar as a field delimiter. – Sort or filter the log using various spreadsheet capabilities. 37
  • 38. Outline  Code quality and Code Standards.  Debugging, logging etc.  Testing. 38
  • 39. Testing  Not closely integrated with development prevents measurement of the progress of development - can't tell when something starts working or when something stops working.  JUnit to cheaply and incrementally build a test suite that helps to: – measure your progress, – spot unintended side effects. – focus your development efforts. 39
  • 40. JUnit  Automatic testing framework. – Acceptance tests. – Integration test. – Unit test.  Reports the number of defects graphically.  May create many tests for each method. 40
  • 41. JUnit Example  Pay attention to the interplay of the code and the tests. – The style: to write a few lines of code, then a test that should run, – or even better: to write a test that won't run, then write the code that will make it run.  The program presented solves the problem of representing arithmetic with multiple currencies. 41
  • 42. Example: Money class Money { private int fAmount; private String fCurrency; public Money(int amount, String currency) { fAmount= amount fCurrency= currency; } public int amount() { return fAmount; } public String currency() { return fCurrency; } } 42
  • 43. JUnit  JUnit defines how to structure your test cases and provides the tools to run them.  You implement a test in a subclass of TestCase. 43
  • 44. Example: Money public Money add(Money m) { return new Money(amount()+m.amount(), currency()); } 44
  • 45. Junit  Define MoneyTest as a subclass of TestCase.  Put MoneyTest in the same package as the classes under test access to the package private methods. – Add method testSimpleAdd, that will exercise the simple version of Money.add() above. – A JUnit test method is an ordinary method without any parameters. 45
  • 46. Example: MoneyTest public class MoneyTest extends TestCase { //… public void testSimpleAdd() { Money m12JPY= new Money(12, “JPY"); // (1) Money m14JPY= new Money(14, “JPY"); Money expected= new Money(26, “JPY"); Money result= m12JPY.add(m14JPY); // (2) assert(expected.equals(result)); // (3) } } 46
  • 47. Developing Tests public void testEquals() { Money m12CHF= new Money(12, "CHF"); Money m14CHF= new Money(14, "CHF"); assert(!m12CHF.equals(null)); assertEquals(m12CHF, m12CHF); assertEquals(m12CHF, new Money(12, "CHF")); // (1) assert(!m12CHF.equals(m14CHF)); } 47
  • 48. Developing Tests public boolean equals(Object anObject) { if (anObject instanceof Money) { Money aMoney= (Money)anObject; return aMoney.currency().equals(currency()) && amount() == aMoney.amount(); } return false; }  Override the method hashCode whenever you override method equals. 48
  • 49. Assertions  Verification in JUnit by calling assert which is inherited from TestCase. – Assert triggers a failure that is logged by JUnit when the argument isn't true. – Since assertions for equality are very common, TestCase defines an assertEquals convenience method. Logs the printed value of the two objects if they differ. – Shows why a test failed in a JUnit test result report. Logged as a string representation created by toString. 49
  • 50. Test Fixture public class MoneyTest extends TestCase { private Money f12CHF; private Money f14CHF; protected void setUp() { f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); } } 50
  • 51. Tests Refactored public void testEquals() { assert(!f12CHF.equals(null)); assertEquals(f12CHF, f12CHF); assertEquals(f12CHF, new Money(12, "CHF")); assert(!f12CHF.equals(f14CHF)); } public void testSimpleAdd() { Money expected= new Money(26, "CHF"); Money result= f12CHF.add(f14CHF); assert(expected.equals(result)); } 51
  • 52. Running of Tests  Two additional steps are needed to run the two test cases: 1. define how to run an individual test case, 2. define how to run a test suite.  JUnit supports two ways of running single tests: – static. – dynamic. 52
  • 53. Test Case: Static  Overrides the runTest method inherited from TestCase and call the desired test case. – Convenient way: anonymous inner class. – Note: each test must be given a name to identify it if it fails. TestCase test = new MoneyTest("simple add") { public void runTest() { testSimpleAdd(); } }; – A template method in the super-class will make sure runTest is executed when the time comes.  Dynamic: TestCase test = new MoneyTest("testSimpleAdd"); 53
  • 54. Test Suite: Dynamic  Illustration of the creation of a test suite with the dynamic way to run a test: – You only pass the class with the tests to a TestSuite and it extracts the test methods automatically. public static Test suite() { return new TestSuite(MoneyTest.class); } 54
  • 55. Test Suite: Static public static Test suite() { TestSuite suite= new TestSuite(); suite.addTest(new MoneyTest("money equals"){ protected void runTest() { testEquals(); } } ); suite.addTest(new MoneyTest("simple add") { protected void runTest() { testSimpleAdd(); } } ); return suite; } 55
  • 56. JUnit Review  In general: development will go much smoother writing tests a little at a time when developing.  When coding the imagination of how the code will work. Capture the thoughts in a test.  Test code is just like model code in working best if it is factored well. 56
  • 57. JUnit Review  Keeping old tests running is just as important as making new ones run.  The ideal is to always run all of your tests.  When you are struck by an idea, defer thinking about the implementation. First write the test. Then run it. Then work on the implementation. 57
  • 58. Testing Practices  Martin Fowler: "Whenever you are tempted to type something into a print statement or a debugger expression, write it as a test instead.”  Only a fraction of the tests are actually useful. – Write tests that fail even though they should work, or tests that succeed even though they should fail. – Think of it is in cost/benefit terms. You want tests that pay you back with information. 58
  • 59. Testing Practices  Receive a reasonable return on your testing investment: – During Development. – During Debugging.  Caution: – Once you get them running, make sure they stay running.  Ideally, run every test in the suite every time you change a method. Practically, the suite will soon grow too large to run all the time. 59
  • 60. Testing Practices  Try to optimise your set-up code so you can run all the tests.  Or, – create special suites that contain all the tests that might possibly be affected by your current development. – run the suite every time you compile. – make sure you run every test at least once a day: overnight, during lunch, during one of those long meetings…. 60
  • 61. Q&A 61