61
LOGO Code Quality, Maintainability, Reusability, Debuggi ng, Testing Nguyen Trung Thanh 1

Coding convention

Embed Size (px)

Citation preview

Page 1: Coding convention

LOGO

Code

Quality, Maintainability, Reusability, Debuggi

ng, TestingNguyen Trung Thanh

1

Page 2: Coding convention

Outline

2

Code Quality & Standards.

Debugging, logging etc.

Testing.

Page 3: Coding convention

Key Principles; Coding

3

Understandability

Coding Convention

High cohesion

Loose coupling

Code Formatting

Consistent Naming

Information hiding

Valuable Comments

Page 4: Coding convention

Code Standards

4

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/CodeConvTOC.doc.html.

Page 5: Coding convention

Code Standards

5

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.

Page 6: Coding convention

Code Standards

6

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.

Page 7: Coding convention

Code Standards

7

Do it right the first time !

Your professionalism is expressed by

applying code standards !

Document any deviations!

Page 8: Coding convention

Formatting

8

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.

Page 9: Coding convention

Examples (1)

9

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

Page 10: Coding convention

Examples (2)

10

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.

Page 11: Coding convention

Naming

11

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.

Page 12: Coding convention

Naming

12

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.

Page 13: Coding convention

Java Naming Convention

13

Package: scope.mypackage

Classes: MyClass

Methods: myMethod

Constants: MY_CONSTANT

Attribute: myAttribute

Variable: myVariable

Page 14: Coding convention

Parameters

14

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

Page 15: Coding convention

Comments; Why, when, where, what

15

Why: To be able to find out what a operationdoes 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.

Page 16: Coding convention

Project Organisation:Spider-web

16

::theoretical

::pck_stream

::pck_cargo

::choke

::lift_account

::pck_stock

::pck_cargo_doc

::units

::lagkodeserver

::pck_check

::pck_stream_network

::pck_well

::sep_test

::pck_flowline

::pck_facility

::pck_system

::mathlib

::pck_regression

::calc_stream::comp_analysis

::regularity

::well_node

::puf

::summarise

::tbp_product

::transfer_basis

::value_adjust

Page 17: Coding convention

Architecture; How to Avoid Spider-web

17

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.

Page 18: Coding convention

Refactor to a New Architecture

18

::EcBpStreamFlare

::EcDpStream ::EcDpWellReservoir

::EcBpStreamFluid::EcBpStreamShipper ::EcDpWellStream

::EcDpStreamFluid::Theoretical

::EcBpStream

::EcDpDerivedStream

::calc_stream

::comp_analysis

Page 19: Coding convention

Information Hiding

19

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.

Page 20: Coding convention

Binding

20

Bind constants as late as possible

– Do not use magic Numbers, avoid hard-coded valuestotalFooDay = 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

Page 21: Coding convention

Java Exceptions

21

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.

Page 22: Coding convention

Java Exceptions

22

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.

Page 23: Coding convention

Code Defensively

23

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.

Page 24: Coding convention

Code Defensively

24

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.).

Page 25: Coding convention

Summary

25

Remember your code should be

understandable.

Maintenance is often up to 70% of a total

project cost.

Use quality control.

Page 26: Coding convention

Outline

26

Code quality and Code Standards.

Debugging, logging etc.

Testing.

Page 27: Coding convention

Debugging

27

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

Page 28: Coding convention

Application Logging: What and Why?

28

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.

Page 29: Coding convention

System Event Categories

29

Levels:

– CRITICAL_ERROR. (Highest - 1)

– ERROR.

– WARNING.

– INFORMATION.

– DETAIL.

– TRACE. (Lowest - 6)

Page 30: Coding convention

Logging Granularity

30

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.

Page 31: Coding convention

Logging Events

31

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.

Page 32: Coding convention

Configuring the Logs

32

Configuration from a properties file.LogFileExtension = log

LogFilePath = c:\\temp\\

LoggingLevel = 2

LoggingMechanism = log.StandardErrLoggingMechanism

LogFieldSeparator = |

Page 33: Coding convention

Configuring the Logs

33

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.

Page 34: Coding convention

Configuring the Logs

34

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);

Page 35: Coding convention

Configuring the Logs

35

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.

Page 36: Coding convention

Reading the Logs

36

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.

Page 37: Coding convention

Reading the Logs

37

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.

Page 38: Coding convention

Outline

38

Code quality and Code Standards.

Debugging, logging etc.

Testing.

Page 39: Coding convention

Testing

39

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.

Page 40: Coding convention

JUnit

40

Automatic testing framework.

– Acceptance tests.

– Integration test.

– Unit test.

Reports the number of defects graphically.

May create many tests for each method.

Page 41: Coding convention

JUnit Example

41

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.

Page 42: Coding convention

Example: Money

42

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;

}

}

Page 43: Coding convention

JUnit

43

JUnit defines how to structure your test

cases and provides the tools to run them.

You implement a test in a subclass of

TestCase.

Page 44: Coding convention

Example: Money

44

public Money add(Money m) {

return new Money(amount()+m.amount(), currency());

}

Page 45: Coding convention

Junit

45

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.

Page 46: Coding convention

Example: MoneyTest

46

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)

}

}

Page 47: Coding convention

Developing Tests

47

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));

}

Page 48: Coding convention

Developing Tests

48

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.

Page 49: Coding convention

Assertions

49

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.

Page 50: Coding convention

Test Fixture

50

public class MoneyTest extends TestCase {

private Money f12CHF;

private Money f14CHF;

protected void setUp() {

f12CHF= new Money(12, "CHF");

f14CHF= new Money(14, "CHF");

}

}

Page 51: Coding convention

Tests Refactored

51

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));

}

Page 52: Coding convention

Running of Tests

52

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.

Page 53: Coding convention

Test Case: Static

53

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");

Page 54: Coding convention

Test Suite: Dynamic

54

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);

}

Page 55: Coding convention

Test Suite: Static

55

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;

}

Page 56: Coding convention

JUnit Review

56

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.

Page 57: Coding convention

JUnit Review

57

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.

Page 58: Coding convention

Testing Practices

58

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.

Page 59: Coding convention

Testing Practices

59

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.

Page 60: Coding convention

Testing Practices

60

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….

Page 61: Coding convention

Q&A

61