Top Banner
Quality in coding 1 Quality in Coding Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet by Joey Paquet
35

Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Dec 27, 2015

Download

Documents

Godwin McDaniel
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 1

Quality in CodingQuality in Coding

DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY

2006

by Joey Paquetby Joey Paquet

Page 2: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 2

Outline

IntroductionIntroduction Software qualitiesSoftware qualities Quality vs costQuality vs cost Cross-related qualitiesCross-related qualities Code qualitiesCode qualities Practices to achieve quality codePractices to achieve quality code ReferencesReferences

Page 3: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 3

Introduction

All software must expose some qualities These necessary qualities are different from one software to another

Many of these qualities are not directly related to the code itself Though in the end, they are all indirectly related to the code

The code itself has some qualities that are not necessarily externally visible

Page 4: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 4

Software qualities

Reliability Modifiability Maintainability Understandability Adaptability Reusability Efficiency Portability Traceability of artifacts Fault tolerance Backward-compatibility Cost-effectiveness Robustness High-performance

Good documentation Well-defined interfaces User-friendliness Rapid development Minimum # of errors Readability Ease of learning Ease of remembering Ease of use Increased productivity Low-cost Flexibility

Page 5: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 5

Cross-related qualities

Some qualities are cross-related (positively or negatively) Functionality vs. Usability Cost vs. Robustness Efficiency vs. Portability Rapid development vs. Functionality Cost vs. Reusability Backward Compatibility vs. Readability Coupling vs Maintainability etc

Page 6: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 6

Quality vs cost

Achieving quality inevitably implies cost You want to avoid increasing cost to increase unnecessary qualities

Cost investment towards a certain quality should be proportional to the importance of this quality, i.e. justification is necessary.

Thus, determining the right qualities is a primordial activity Some simple practices can be used to increase quality with minimal

cost

Page 7: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 7

Code qualities

Page 8: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 8

Code qualities

Reliability Modifiability Maintainability Adaptability Reusability Efficiency Portability Traceability of artifacts Fault tolerance Backward-compatibility Cost-effectiveness Robustness High-performance

Cohesion Coupling Modularity Information hiding Encapsulation Readability Understandability Low redundancy

Page 9: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 9

Code qualities

Modularity

A good design usually consists of a collection of well-defined, discrete components or modules.

There are various ways of organizing the modules (software architecture)

The important thing is to avoid a jumble of classes connected in arbitrary ways.

Several levels of abstraction in modularity.

Modularity does not necessarily lead to good cohesion and coupling

Page 10: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 10

Code qualities

Cohesion

A module is cohesive, or has high cohesion, if its internal parts are closely related towards the achievement of a clear purpose.

Every sub-component is working towards this goal.

Similar concept as for “team cohesion”

A simple test of cohesion is to try to describe the module concisely. A complex module description or complex interface is often an

indication of poor cohesion

Low class cohesion is often called a “schizophrenic class” [Dr. Dan]

Page 11: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 11

Code qualities

Cohesion (continued…)

Coincidental: parts are unrelated to one another

Logical: logically related functions or data elements are placed in the same

component. E.g. all “input” features are put in the same component, either from files, or from the network.

Temporal: functions that are executed in sequence are put in a component. E.g.

system initialization procedures. Procedural:

functions that sequentially aim at the production of a result are put in the same component. E.g. capture the data, validate, create a record, and save it.

Page 12: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 12

Code qualities

Cohesion (continued…)

Communicational: functions are associated because they operate on or produce the same data

set. E.g. book inventory is used for both accounting and managing orders. Sequential:

the output from one part of a component is input to the next part. E.g. compilers.

Functional: every processing element is essential to the performance of a single

functionality, and all essential elements are contained in one component. A functionally cohesive component not only performs the functionality for

which it is designed, but also performs only that functionality and nothing else.

It is thus more likely that changing this particular functionality will affect only one component.

Page 13: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 13

Code qualities

Coupling

Two modules are coupled if they depend on each other in any way. As with cohesion, there are various degrees of coupling. Unlike cohesion, less coupling is better.

“coupling refers to the strength of a connection between two [classes]. Coupling is a complement to cohesion. Cohesion describes how strongly the internal content of a [class] are related to each other. Coupling describes how strongly a [class] is related to other [classes]. The goal is to create [classes] with internal integrity (i.e. strong cohesion) and small, direct, visible, and flexible relations to other [classes] (i.e. loose coupling).” [Constantine 1975, McConnell 1993]

Example: façade pattern Precept: “no two dots in a call”

Page 14: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 14

Code qualities

Coupling (continued…)

Content : one component actually modifies another. E.g. one component modifies an

internal data item in another component, or when one component branches into the middle of another component.

Common : data are accessible from a central store in both components. E.g. global

variables. it can be difficult to determine which component is responsible for having set a variable to a particular value.

Control : one component passes parameters to control the execution of another

component. E.g. setting a “flag”. Sometimes acceptable, but should minimize the amount of controlling information that must be passed from one component to another and to localize control to a fixed and recognizable set of parameters forming a well-defined interface.

Page 15: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 15

Code qualities

Coupling (continued…)

Stamp : a data structure is used to pass information from one component to another,

and the whole data structure is passed. Bad if some of the data is not used. Data :

a restriction of stamp coupling, where data is passed to the called component, but where only the necessary information is passed. Ideally, all informations are passed as separate parameters, even though they come from the same data structure.

Uncoupled : no interconnections at all. Possible?

Page 16: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 16

Code qualities

Testability

Testability tends to improve all other qualities, as tests permit to measure quality and monitor them

Real testability lies in reproducibility of testing at minimal cost (e.g. using a testing framework as JUnit)

Testability requires clear and simple specifications (requirements, interfaces)

Low testability is often a sign of deficient code qualities (modularity, coupling, readability)

Page 17: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 17

Code qualities

No redundancy

Redundancy is an indication of poor design

Writing tests can often help detect redundancy. The necessity of similar test on different components is an indication.

Sometimes its is quicker to code by redundancy. To fix redundancy, use refactoring.

Construction of complex objects is often a source of redundancy. Use “encapsulating construction” to avoid it, e.g. through builder patterns.

Page 18: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 18

Code qualities

Encapsulation/Information hiding

Highly related to cohesion and coupling, but sufficiently important to be separated from them. High coupling and low information hiding are related High information hiding prevents coupling to be introduced

If designers do not follow the principles of information hiding, the system will contain possible dependencies that will make understandability and maintenance a nightmare.

Note that information hiding can be overridden by privacy leaks, most notably through passing and returning references to objects

An important quality to be increased through refactoring operations

Page 19: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 19

Code qualities

Readability/Understandability

Readable code is more understandable Readability can be improved by:

Consistent use of coding standards and naming convention Simple, usable and up to date documentation (e.g. using Javadoc)

Understandability is also influenced by cohesion and coupling

They both have a great influence on maintainability, and productivity in general, especially in change-prone projects such as when using XP or other incremental software development model.

Page 20: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 20

Code qualities

Fault tolerance

A good design/code should be tolerant of both external and internal errors.

It is important but straightforward to protect the system against most external errors. The key step is to validate all inputs to the system carefully, so that the system rejects inappropriate data and processes only “good” data.

Even after validation, internal errors may still cause the system to fail. Dividing by zero or computing the square root of a negative number causes most processes to raise a signal. If the signal is not handled and processed correctly, the system may crash.

How to achieve: Write tests first Component/system duplication Write fault-detection-enabled mutators Use exception handling to report errors and prevent crashing

Page 21: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 21

Code qualities

Simplicity

Always choose the simplest design when a choice comes in. (if both designs meet the requirements/specifications)

Designer should try to remove all unnecessary complexity from the system (can be done retroactively through refactoring).

Simplifying is hard and requires experience. Examples:

a design diagram is hard to read if it contains many crossing lines. If you redraw it to reduce the number of intersections, you will understand it better and may be able to simplify it.

A large number of links to a class may indicate low cohesion or high coupling. Increasing cohesion and reducing coupling will tend to simplify a design.

Don't worry about efficiency during design.

Page 22: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 22

Practices to achieve quality code

Page 23: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 23

Practices to achieve quality code

Write tests first

Testing after the code has been produced introduces a bias : test cases are written according to the code.

Writing test cases before the code forces you to think in advance of what the software is supposed to do and determine how it reacts to normal situations, and to abnormal situations. Then it becomes easier to write the code, and it is less likely that you will have to change the code to adapt it to a situation you did not expect.

In other words, the tests are the “code specifications”.

Page 24: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 24

Practices to achieve quality code

Write tests first (continued…)

This is related to: interface specifications “designing by interfaces” [Gamma et al.] “design by contract” [Meyer] Test-driven development [Beck, Astels]

Increases maintainability, understandability of the code.

Some find that this is counterproductive.

However, when used in combination with a testing framework (e.g. JUnit), it justifies the cost investment by having proper testing in place as the code is being developed and later changed.

Page 25: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 25

Practices to achieve quality code

Encapsulate by convention, reveal by need

In a famous paper written in 1972, David Parnas set out the principles of information hiding:

“The developer of a software component must be provided with all the information necessary to carry out the given responsibilities assigned to the component, and should be provided with no other information.”

This principle is very general and can be applied at all abstraction levels and in most software development activities.

Page 26: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 26

Practices to achieve quality code

Encapsulate by convention, reveal by need (continued…)

According to [Shalloway, Bain], there are several types of encapsulation:

Data encapsulation: hiding data members of a class using private data members and providing accessors and/or mutators.

Implementation encapsulation: do not let a client object know the implementation details of a method. Use clear and minimal interfaces that do not use “control coupling”.

Type encapsulation: hiding the type of objects being used, e.g. factory and abstract factory patterns, abstract classes.

Construction encapsulation: hiding how objects are being constructed, e.g. singleton pattern, builder pattern.

Design encapsulation: the internal parts of a component are hidden. A limited interface is provided, e.g. using a façade pattern.

Page 27: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 27

Practices to achieve quality code

Avoid redundancy

Redundant code is often introduced when a new requirement emerges that is a slight variation of an existing one for which there is already an implemented solution.

Quick solution: copy the code, make a slight change to it to accommodate for differences.

Problem: it is then likely that if one is changed, the other also needs to be changed, and that “dependency” is not necessarily apparent.

Better solution: use the same objects/procedure/design and make it provide a solution to both requirements, using if/switch or #ifdef to make the code behave differently in different situations.

Page 28: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 28

Practices to achieve quality code

Don’t do more than you need

Similar to XP’s “simple design”. However, “simplicity” is subjective.

Determine what needs to be done, do it, and don’t invest in unnecessary complexity.

Don’t overdo this. It does not mean “don’t try to foresee”, or “software architecture is not important”. Think ahead, but not too much, and don’t invent features that are not expressed needs.

Saves time by developing only necessary structure Allows you to concentrate on what is really important now All code that you write “for later” has to be maintained, documented,

etc before it is actually used. It is also likely that the system changes introduced in the mean time will invalidate this code/solution.

Page 29: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 29

Practices to achieve quality code

Treat conceptually similar things the same way

Similar to “find what varies and encapsulate it” [Gamma et al.] “information hiding” [Parnas]

If a client object is using several different objects/services that conceptually do the same thing, all should be exposed to it in the same manner, i.e. using the same interface.

That might mean to introduce unnecessary interface elements to simpler components to match the complexity of more complex ones.

Leads to adaptable code: One can add more of such similar services, as they are all using the

same interface. Client objects can use these new services with minimal changes, e.g.

using different parameter values on calling a method

Page 30: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 30

Practices to achieve quality code

Favor composition over class inheritance

If you need to vary behavior, don’t achieve it by creating a subclass Rather, create a separate “behavioral class” hierarchy and use

composition to link this behavior to the original class. Positive effects:

Encapsulates common behavioral classes, increases maintainability Permits better reuse through a common interface

Related to most GoF patterns

Page 31: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 31

Practices to achieve quality code

Design to interfaces

Upon writing any component or class, first design its interface, i.e. determine what information, behavior (or services) it needs to expose to the exterior.

Class level: determine what is public and private Component level: determine what services are necessary to be

exposed, use patterns like a façade to expose necessary services, and enforce that only the façade is used to access this component.

Related to : “design by contract”, UML responsibilities CRC cards [Cunningham]

Page 32: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 32

Practices to achieve quality code

Separate use from construction

Two important topics in designing software: How instances will be used (i.e. its public interface) How the instances are created (i.e. constructor design)

In the case of complex classes, construction can be a complex operation, e.g. when A class is composed of other classes (I.e. has members that are

themselves complex classes) These members can take different forms depending on the context of use

As much as possible, the complexity of construction, as well as the variation factors should be hidden from the outside.

For example, builder pattern, factory pattern

Page 33: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 33

Practices to achieve quality code

Refactor code as needed

“Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet it improves its internal structure.” [Fowler]

Examples: Extract a method that needs to be generalized (see “favor composition

over inheritance”) Move a method Rename a method Use polymorphism, templates to generalize common code Create and reorganize packages

The more changes are likely, the more refactoring is important.

Page 34: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 34

Practices to achieve quality code

Prototyping

If you are not sure whether a solution will actually work, it may be a good idea to prototype it.

Same if you have different alternatives and it is not clear which one is most appropriate

Prototyping means implementing the design in a “quick and dirty” way, in order to get feedback.

Development effort of the prototype should be highly focused on getting proper feedback.

Be very careful if you reuse the prototype code in the operational version.

Page 35: Quality in coding 1 Quality in Coding DEPARTMENT OF COMPUTER SCIENCE AND SOFTWARE ENGINEERING CONCORDIA UNIVERSITY 2006 by Joey Paquet.

Quality in coding 35

• Test-driven development.• www.agiledata.org/essays/tdd.html

• Shalloway, Bain. Code qualities and coding practices. • www.netobjectives.com/download/Code%20Qualities%20and

%20Practices.pdf -

References