HIGH QUALITY CODE

TABLE OF CONTENTS

  • Naming, Formatting, Documentation
  • Defensive programming
  • Refactoring
  • Unit testing
  • SOLID principles

Naming, Formatting, Documentation

Software Quality

  • External quality
    • Does the software behave correctly?
    • Are the produced results correct?
    • Does the software run fast?
    • Is the software Ul easy -to -use?
    • Is the code secure enough?

Software Quality (2)

    Internal quality
  • Is the code easy to read and understand?
  • Is the code well structured?
  • Is the code easy to modify?

What is High -Quality Programming Code?

    High-quality programming code:
  • Easy to read and understand
  • Easy to modify and maintain
  • Correct behavior in all cases
  • Well tested
  • Well architectured and designed
  • Well documented
  • Self -documenting code
  • Well formatted

Code Conventions

    Code conventions are formal guidelines about the style of the source code:
  • Code formatting conventions - indentation, whitespace, etc.
  • Naming conventions - PascalCase or camelCase, prefixes, suffixes, etc.
  • Best practices - Classes, interfaces, enumerations, structures, inheritance, exceptions, properties, events, constructors, fields, operators, etc.

General Guidelines

  • Always use English. How will you feel if you read Vietnamese code with variables named in Vietnamese?
  • English is the only language that all software developers speak
  • Avoid abbreviations e.g. scrpCnt vs. scriptsCount
  • Avoid hard-to-pronounce names e.g. dtbgRegExPtrn vs. dateTimeBulgarianRegExPattern

Naming Classes

  • Always prefer meaningful names
      Names should answer these questions:
    • What does this class do?
    • What is the intent of this variable?
    • What is this variable / class used for?
  • Use the following formats for classes:
    • [Noun]
    • [Adjective] + [Noun]
    • e.g. Student, FileSystem, BinaryTreeNode, Constants, TestUtils

Naming Classes (2)

  • How long could be the name of a class/interface/enum?
    • The name should be as long as required
    • Your IDE has autocomplete, right?

Naming Methods

    Methods naming guidelines
  • Method names should answer the question: What does this method do?
  • If you cannot find a good name for a method, think about whether it has a clear intent

public class ClientActivity {
  public void ClearStatistics() {
  	//...
  }
  public void CalculateStatistics() {}
}
						 

Naming Methods (2)

  • Methods should have a single purpose!
  • Otherwise they cannot be named well
  • How to name a method that creates annual incomes report, downloads updates from Internet and scans the system for viruses?
  • Methods that have multiple purposes (weak cohesion) are hard to be named
    - Need to be refactored instead of named
    - Use consistent naming in the entire project
  • The name should be as long as required

Naming Variables

  • Should explain the purpose of the variable
  • If you can't find good name for a variable, check if it has a single purpose
  • Names should be consistent in the project
  • Give to boolean variables names that imply true or false Use positive boolean variable names
  • Do you really think temporary variables exist? Temporary variables can always be named better than temp or tmp

Code Formatting

  • Good formatting goals
    • To improve code readability
    • To improve code maintainability
  • Fundamental principle of code formatting:
    • The formating of the source code should disclose its logical structure.
    • Any (consistent) formatting style that follows the above principle is good
    • Good formatting don't affect speed, memory use or other aspects of the program

Code Formatting (2)

    Take advantage of your IDE to help formatting the code [Ctrl+K+D]
  • Automatic alignment
  • Indentation Style Code analysis

Project Documentation

    Consists of documents and information
  • Both inside the source-code and outside
  • External documentation
    • At a higher level compared to the code
    • Problem definition, requirements, architecture, design, project plans, test plans. etc.
    • GhostDoc
  • Internal documentation
    • Lower-level - explains a class, method or a piece of code
    • e.g. JIRA Wiki

Self-Documenting Code

  • Code that relies on good programming style
    - To carry major part of the information intended for the documentation
  • Self-documenting code fundamental principles
    - The best documentation is the code itself.
    - Make the code self-explainable and self-documenting, easy to read and understand.
    - Do not document bad code, rewrite it!
  • e.g. Orchard CMS

Effective Comments

  • Effective comments do not repeat the code
  • They explain it at a higher level and reveal non-obvious details
  • The best software documentation is the source code itself - keep it clean and readable!
  • Comment anything that gets around an error or an undocumented feature

Effective Comments (2)

  • Self-documenting code is self-explainable and does not need comments
  • Simple design, small well named methods, strong cohesion and loose coupling, simple logic, good variable names, good formatting, ...

//Resets the score to 0
score = 0;
						
OR

//Resets the score to 0, because the game is starting over
score = 0;
						

Defensive programming

“Programming today is a race between software engineers striving to build bigger and better idiot -proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.”
~ Rick Cook, The Wizardry Compiled (1989)

Defensive programming

  • Similar to defensive driving - you are never sure what other drivers will do.
  • Expect incorrect input and handle it correctly
  • Think not only about the usual execution flow, but consider also unusual situations

Refactoring

Refactoring

“to improve the design and quality of existing source code without changing its external behavior.”
~ Martin Fowler
  • It is a step by step process that turns the bad code into good code
  • Based on "refactoring patterns", well-known recipes for improving the code

Refactoring (2)

    Why we need refactoring?
  • Code constantly changes and its quality constantly degrades (unless refactored)
  • Requirements often change and code needs to be changed to follow them
  • Bad smell in the code indicate need of refactoring
  • Unit tests guarantee that refactoring does not change the behavior
  • If there are no unit tests, write them!

Refactoring Process

  • Save the code you start with.
    - Check-in or backup the current code
  • Make sure you have tests to assure the behavior after the code is refactored
  • Do refactorings one at a time
  • Keep refactorings small
  • Don't underestimate small changes
  • Run the tests and they should pass / else revert
  • Check-in

Refactoring Tips

  • Keep refactorings small
  • One at a time
  • Make a checklist / TODO list
  • Check-in/commit frequently
  • Add tests cases
  • Review the results
  • Pair programming
  • Use tools. IDE + Add-ons e.g. ReSharper

Unit testing

Unit testing

“Program testing can be used to show the presence of bugs, but never to show their absence!”
~ Edsger Dijkstra, [1972]
  • A unit test is a piece of code written by a developer that exercises a very small, specific area of functionality of the code being tested.

Unit testing (2)

  • Tests are specific pieces of code
  • Those should be written by developers, not by QA engineers!
  • Unit tests are released into the code repository (TFS / SVN / Git) along with the code they test
  • Unit testing framework is needed
    - NUnit, Junit, TestNG, MbUnit, Gallio, etc.

Unit testing (3)

  • All classes should be tested
  • All methods should be tested
    • Trivial code may be omitted e.g. property getters and setters
    • Private methods can be omitted (decide per case!). Some gurus recommend to never test private methods. This can be debatable!
  • Ideally all unit tests should pass before check-in into the source control repository

Assertions

  • Predicate is a true / false statement
  • Assertion is a predicate placed in a program code (check for some condition)
    • We expect the predicate to be always true at that place
    • If an assertion fails, the method call does not return and an error is reported
  • The 3A Pattern
    • Arrange all necessary preconditions and inputs
    • Act on the object or method under test
    • Assert that the expected results have occurred

SOLID principles

SOLID Principles

  • SOLID
    • SRP - Single Responsibility Principle
    • OCP - Open/Closed Principle
    • LSP - Liskov Substitution Principle
    • ISP - Interface Segregation Principle
    • DIP - Dependency Inversion Principle

Other Principles

  • DRY - "Don't repeat yourself". Aimed at reducing repetition of information of all kinds.
  • YAGNI - "You aren't gonna need it". A programmer should not add functionality until deemed necessary.
  • KISS - "Keep it simple, stupid". States that most systems work best if they are kept simple rather than made complicated; therefore simplicity should be a key goal in design and unnecessary complexity should be avoided.
office@e-dojo.it

EXERCISE

Problem 1: Naming, Formatting, Comments

Using the gained so far knowledge of Naming, Formatting and Comments revisit your code from all the classwork exercises till now.

Problem 2: Unit testing

Using the gained so far knowledge of Unit testing, create tests for at least 3 of your classes from all the classwork exercises till now.

EXERCISE

Problem 3: Refactoring

Using the gained so far knowledge of OOP, SOLID principles, cohesion and coupling, refactor least 3 of your classes from all the classwork exercises till now.