SlideShare a Scribd company logo
1 of 27
Clean code
Roy Nitert
18-6-2013
GEWIS lunchlezing
Clean code agenda
 Quality
 Readability
 Code smells
 Clean code characteristics
 Single responsibility principle
 Code comments
 Small methods
 Descriptive names
 Applying clean code
© Sioux 2012 | Confidential | 2
Quality
 Poor SW quality cost $500 billion per year
 Customer expectation, free of deficiencies,
easy to use
 Improve quality: testing, requirements,
documentation, code reviews
 Studies have shown that poor readability
correlates strongly with defect density.
© Sioux 2012 | Confidential | 3
Requirements
© Sioux 2012 | Confidential | 4
Readability
 To make it easier to understand and cheaper
to modify (maintainability) software
 The code you write will be read more times
than it was written and by more people.
 “Any fool can write code that a computer can
understand. Good programmers write code
that humans can understand.” - Martin Fowler
© Sioux 2012 | Confidential | 5
Recognizing clean code
© Sioux 2012 | Confidential | 6
Code smells
 A „smell‟ in code is a hint that something
might be wrong with the code
 Duplicated code
 Long switch/if statements
 Long methods
 Poor method/variable names
 In-line comments
 Large classes
© Sioux 2012 | Confidential | 7
What is clean code ?
Characteristics of clean code:
 Small methods and classes
 Descriptive names
 Not too many parameters in methods (and no flags)
 No obvious or irrelevant comments (code must be
self describing)
 No redundancy (DRY: don‟t repeat yourself)
 No magic numbers
 Single responsibility principle (SRP)
 Uniform coding style
© Sioux 2012 | Confidential | 8
SRP: Single Responsibility
Principle
 every object should have a
single responsibility, and that
responsibility should be entirely
encapsulated by the class.
 a class or module should have
one, and only one, reason to change
 If class names have „manager‟ or „processor‟ in
them, they probably have multiple
responsibilities
 the "S" in "SOLID" stands for the single
responsibility principle (“Principles Of OOD”, Robert C. Martin)
© Sioux 2012 | Confidential | 9
Comments
© Sioux 2012 | Confidential | 10
Comments
 Comments do not make up for bad code
 Good: Legal, explanation, TODO
 Bad: redundant, misleading, journal, headers
 Don‟t use a comment when you can use a
function or a variable
© Sioux 2012 | Confidential | 11
// Returns an instance of the Responder being tested.
protected abstract Responder responderInstance();
protected abstract Responder responderBeingTested();
Small methods
© Sioux 2012 | Confidential | 12
 They should be very very small
 Should do one thing, do it well, do it only
 One level of abstraction
 Should read like a narrative
 Should not have sections
 Blocks within if, else and while
statements should be one line long
/*---------------------------------------------------------------------------*/
int PO_rq_do_service( PO_object_t *object_p,
DDXA_var_string_t *document_type,
DDXA_var_string_t *service,
DDXA_var_string_t *document_path,
DDXA_var_string_t *input_file_path,
DDXA_var_string_t *output_file_path,
ASML_bool use_compression,
PLXAtimestamp *time_stamp,
POXA_var_string_array_t *parameters,
DDXA_var_string_t *user_name,
POXA_DocMetaDataListType *list,
POXA_var_string_array_t *error_messages )
/*
* Description : Execute the requested service. The requested service is specified in
* the 'service' parameter. The following services are defined:
* put (=download), get (=upload), list, verify, and delete).
*
* Input(s) : document_type - type of document ( e.g. ADELfoo )
* service - Name of the service (get, put, verify, delete, list)
* document_path - Service = get, delete, list:
* Document identification (e.g. path/to/folder/foo.xml)
* - Service = put, verify:
* Not used.
* input_file_path - Service = put, verify:
* Name of XML formatted file (path+name)
* - Service = get, delete, list
* Not used.
* output_file_path - Service = put, verify
* Name of the XML formatted report file (path+name)
* - Service = get
* Name of the XML formatted file (path+name)
* - Service = list
* Name of the XML formatted ADELdirectory file (path+name)
* (for Y* components using generic POxSERVICE interface)
* - Service = delete
* Not used
* use_compression - Flag to indicate incoming document must unzipped and/or
* outgoing document must be zipped.
* time_stamp - Service = get
* Time stamp of subrecipe to get (optional).
* Service = put, verify, delete, list
* Not used.
* parameters - Array of strings pairs containing all the options and
* values from the URL query string.
* user_name - Name of an authenticated user
*
* Output(s) : list - Service = list
* List of document names found, including meta data (used
* for old Y* components NOT using generic POxSERVICE
* interface)
* - Service = put, get, verify, delete
* Not used
* error_messages - Array of error messages.
*
* Returns : OK
* POXA_PARAM_ERR;
* POXA_INVALID_TYPE;
* POXA_ERR_RECIPE_DOES_NOT_EXIST;
* POXA_SYS_ERR;
*
* Notes : The implementation of this function will have the following limitations:
* - UserName: The UserName will be used for a user authorization mechanism.
* This mechanism will not be implemented, the parameter will be ignored.
* - ErrorMessages: The array of error messages will remain empty.
*
* Pre.Cond. :
*
* Post.Cond. :
*/
{
int r = OK;
int r_unzip = OK;
ASML_bool single_zip = FALSE;
ASML_bool is_secs = FALSE;
POXA_DataType data_type = POXA_DATA_TYPE_UNDEFINED;
PODS_SERVICE_ENUM service_value = PODS_SERVICE_UNKNOWN;
char type_name[PODS_MAX_TYPE_LENGTH] = "";
if (( r == OK) && (object_p == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, object_p = NULL"));
}
if (( r == OK) && (document_type == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, document_type = NULL"));
}
if (( r == OK) && (service == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, service = NULL"));
}
if (( r == OK) && (document_path == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, document_path = NULL"));
}
if (( r == OK) && (input_file_path == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, input_file_path = NULL"));
}
if (( r == OK) && (output_file_path == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, output_file_path = NULL"));
}
if ((r == OK) && (time_stamp == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, time_stamp = NULL"));
}
if (( r == OK) && (parameters == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, parameters = NULL"));
}
if (( r == OK) && (user_name == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, user_name = NULL"));
}
if (( r == OK) && (list == NULL))
{
r = PO_ERR_NULL_PARAMETER;
ERXA_LOG(r, OK, ("Parameter Error, list = NULL"));
}
if (( r == OK) && (error_messages == NULL))
{
r = PO_ERR_NULL_PARAMETER;
© Sioux 2012 | Confidential | 13
Long function
if ( (r == OK) && ( strcmp( document_type->buf, "" ) == 0 ) )
{
is_secs = TRUE;
}
if (r == OK)
{
THXAtrace (CC, THXA_TRACE_INT, __func__,
"> (%D, %D, %D, %D, %D, use_compression=%s, %D, %D, %D)",
"document_type", "varstring", document_type,
"service", "varstring", service,
"document_path", "varstring", document_path,
"input_file_path", "varstring", input_file_path,
"output_file_path", "varstring", output_file_path,
(use_compression) ? "yes" : "no",
"time_stamp", "timestamp", time_stamp,
"parameters", POXA_VAR_STRING_ARRAY_T_STR, parameters,
"user_name", "varstring", user_name );
}
if (r == OK)
{
if ( strcmp(service->buf, POXA_SERVICE_GET_STRING) == 0 )
{
if ( data_type == POXA_DATA_TYPE_FILE )
{
service_value = PODS_SERVICE_GET_FILE_PATH;
}
else
{
service_value = PODS_SERVICE_GET;
}
}
else if ( strcmp(service->buf, POXA_SERVICE_PUT_STRING) == 0 )
{
service_value = PODS_SERVICE_PUT;
}
else if ( strcmp(service->buf, POXA_SERVICE_VERIFY_STRING) == 0 )
{
service_value = PODS_SERVICE_VERIFY;
}
else if ( strcmp(service->buf, POXA_SERVICE_DELETE_STRING) == 0 )
{
service_value = PODS_SERVICE_DELETE;
}
else if ( strcmp(service->buf, POXA_SERVICE_LIST_STRING) == 0 )
{
service_value = PODS_SERVICE_LIST;
}
else
{
service_value = PODS_SERVICE_UNKNOWN;
}
}
if (r == OK)
{
if ( ( service_value == PODS_SERVICE_PUT) ||
( service_value == PODS_SERVICE_VERIFY) )
{
/* If compressed file sent source_xml_filename contains the filename of
* xml document and can be anything. Type of document must be retreived
* from the contents of the document itself.
* In case a multi zip file is in the input_file, this call
* will result in NOK, thereforeresult is directed to different result
* variable (r_unzip)
*/
if ( is_secs )
{
if ( use_compression )
{
r_unzip = POGN_unzip_file( input_file_path->buf );
if (r_unzip == OK)
{
single_zip = TRUE;
}
}
/* Get document type from the file. */
r = PODS_get_type_from_doc_file( input_file_path->buf, type_name );
if (r == OK)
{
r = DDXA_var_string_alloc( document_type, type_name );
}
/* Incase of unzip the file will need to be zipped */
if ( single_zip )
{
r_unzip = POGN_zip_file( input_file_path->buf );
}
}
}
else if ( (service_value == PODS_SERVICE_LIST) ||
(service_value == PODS_SERVICE_GET) ||
(service_value == PODS_SERVICE_GET_FILE_PATH) ||
(service_value == PODS_SERVICE_DELETE) )
{
if ( is_secs )
{
/* 'document_type' is empty string -> Document is sent via SX. */
r = PODS_extract_type_from_doc_id( document_path->buf, type_name );
if (r == OK)
{
r = DDXA_var_string_cat( document_type, type_name );
}
else
{
ERXA_LOG(PO_ERR_SYS_ERROR,
r,
("Error: Cannot extract document type and path from'%s'", document_path->buf));
r = PO_ERR_SYS_ERROR;
}
}
}
else
{
ERXA_DEACT( OK, PO_ERR_SYS_ERROR, ( "Unknown service requested." ) );
}
}
if ( r == OK )
{
if ( (service_value == PODS_SERVICE_GET) ||
(service_value == PODS_SERVICE_GET_FILE_PATH) )
{
r = po_rq_handle_service_get(
PO_RQ_ACTION_UPLOAD,
document_type,
document_path,
input_file_path,
output_file_path,
time_stamp,
parameters);
}
else if ( service_value == PODS_SERVICE_PUT )
{
r = po_rq_handle_service_put_verify(
PO_RQ_ACTION_DOWNLOAD,
document_type,
input_file_path,
/*---------------------------------------------------------------------------*/
PO_RQ_ACTION_DOWNLOAD,
document_type,
input_file_path,
output_file_path,
use_compression,
parameters,
TRUE,
single_zip);
}
else if ( service_value == PODS_SERVICE_VERIFY )
{
r = po_rq_handle_service_put_verify(
PO_RQ_ACTION_VERIFY,
document_type,
input_file_path,
output_file_path,
use_compression,
parameters,
FALSE,
single_zip);
}
else if ( service_value == PODS_SERVICE_DELETE )
{
r = po_rq_handle_service_delete(
document_type,
document_path,
input_file_path,
parameters);
}
else if ( service_value == PODS_SERVICE_LIST )
{
r = po_rq_handle_service_list(
document_type,
document_path,
parameters,
output_file_path,
list);
}
else
{
r = PO_ERR_SYS_ERROR;
ERXA_LOG(r, OK, ("Error: unsupported service '%s'", service->buf));
}
}
/* Zip the target file if necessary (put, verify and get). */
if ( ( r == OK ) && use_compression &&
( ( service_value == PODS_SERVICE_GET ) ||
( service_value == PODS_SERVICE_GET_FILE_PATH ) ||
( service_value == PODS_SERVICE_PUT ) ||
( service_value == PODS_SERVICE_VERIFY ) ) )
{
if (single_zip)
{
r = POGN_zip_file(output_file_path->buf);
}
}
/* create POXA errorcode from internal error codes */
if (r != OK)
{
int l = r;
int r_pr = OK;
char message[ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE]= "";
/* createPOXA errorcode frominternal error codes */
switch (l)
{
case PO_ERR_NULL_PARAMETER:
r = POXA_PARAM_ERR;
r_pr = PLXAstr_strlcpy(message,
"NULL parameter passed.",
ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE);
break;
case PO_ERR_INVALID_TYPE:
r = POXA_INVALID_TYPE;
r_pr = PLXAstr_snprintf(message,
ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE,
"Invalid type '%s' provided.",
document_type->buf);
break;
case PO_ERR_NO_INSTANCE_ID_FOUND:
case PO_ERR_OPENING_FILE:
r = POXA_ERR_RECIPE_DOES_NOT_EXIST;
r_pr = PLXAstr_snprintf(message,
ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE,
"File '%s' does not exist.",
input_file_path->buf);
break;
case PO_ERR_GETTING_LIST:
case PO_ERR_GETTING_DATA:
case PO_ERR_STORING_DATA:
case PO_ERR_PUTTING_DATA:
case PO_ERR_VERIFYING_DATA:
case PO_ERR_DELETING_DATA:
r = POXA_SERVICE_FAILED;
r_pr = PLXAstr_snprintf(message,
ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE,
"Service '%s' failed for document type '%s'.",
service->buf,
document_type->buf);
break;
case PO_ERR_SYS_ERROR:
default:
r = POXA_SYS_ERR;
r_pr = PLXAstr_strlcpy(message,
"Internal error occurred.",
ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE);
break;
}
if (r_pr == OK)
{
if ( ( !is_secs ) && ( strcmp( output_file_path->buf, "" ) != 0) )
{
int r_csr = OK;
r_csr = po_rq_create_service_response(output_file_path->buf,
ADELserviceResponse_Error,
r,
message);
if (r_csr != OK)
{
ERXA_DEACT( POXA_SYS_ERR, r_csr, ("") );
}
}
}
else
{
ERXA_DEACT( POXA_SYS_ERR, r_pr, ("") );
}
ERXA_LOG(r, l,
PO_RQ_ACTION_DOWNLOAD,
("Error: Execution of service '%s' with document_type '%s' failed",
service->buf,
document_type->buf) );
}
THXAtrace (CC, THXA_TRACE_INT, __func__, "< (%D, %D) = %R",
"list", POXA_DOCMETADATALISTTYPE_STR, list,
"error_messages", POXA_VAR_STRING_ARRAY_T_STR, error_messages,
r);
return r;
}
Descriptive names
© Sioux 2012 | Confidential | 14
 Names make software readable
 Helps clarify the design in your mind
 Use long names for long scopes
 Avoid encodings
Descriptive names example
Public int x() {
int q = 0;
int z = 0;
for (int kk = 0; kk < 10; kk++) {
if (l[z] == 10) {
q += 10 + (l[z + 1] + l[z + 2]);
z += 1;
} else if (l[z] + l[z + 1] == 10) {
q += 10 + l[z + 2];
z += 2;
} else {
q += l[z] + l[z + 1];
z += 2;
}
}
return q;
} © Sioux 2012 | Confidential | 15
Descriptive names example
Public int score() {
int score = 0;
int frame = 0;
for (int frameNumber = 0; frameNumber < 10; frameNumber++) {
if (isStrike(frame)) {
score += 10 + nextTwoBallsForStrike(frame);
frame += 1;
} else if (isSpare(frame)) {
score += 10 + nextBallForSpare(frame);
frame += 2;
} else {
score += TwoBallsInFrame(frame);
frame += 2;
}
}
return score;
} © Sioux 2012 | Confidential | 16
Parameters / arguments
© Sioux 2012 | Confidential | 17
 Small number: Zero is best, followed by one, two
or three
 More than three is questionable
 Output arguments are counterintuitive
 Boolean arguments (flags) loudly declare than
the function does more than one thing
 Simpler is easy to understand and easy to test
 Reduce number of arguments by creating
objects out of them
Parameters example
Circle makeCircle(double x, double y, double
radius);
public void AlignTaskCanBeStopped(bool
useRealXps);
AlignTaskCanBeStopped(true);
© Sioux 2012 | Confidential | 18
Parameters example
Circle makeCircle(Point center, double radius);
public void AlignTaskCanBeStoppedWith
RealXps();
public void AlignTaskCanBeStoppedWith
SimulatedXps();
© Sioux 2012 | Confidential | 19
Don‟t repeat yourself
© Sioux 2012 | Confidential | 20
 Duplication
 DRY principle (Dave Thomas)
 Once, and only once (Kent Beck)
 Duplication is a missed opportunity for abstraction
 Examples:
o Identical code (copy/paste)
o Switch/case (or if/else) chains
o Similar algorithms
 Design patterns and OO itself are strategies for
eliminating duplication
DRY example
public void scaleToOneDimension( float desiredDimension, float imageDimension) {
if (Math.abs(desiredDimension – imageDimension) < errorThreshold)
return;
float scalingFactor = desiredDimension / imageDimension;
scalingFactor = (float)(Math.floor(scalingFactor * 100) * 0.01f);
RenderOp newImage = ImageUtilities.getScaledImage( image, scalingFactor,
scalingFactor);
image.dispose();
System.gc();
image = newImage;
}
public synchronized void rotate(int degrees) {
RenderOp newImage = ImageUtilities.getRotatedImage( image, degrees);
image.dispose();
System.gc();
image = newImage;
}
© Sioux 2012 | Confidential | 21
DRY example
public void scaleToOneDimension( float desiredDimension, float imageDimension) {
if (Math.abs(desiredDimension – imageDimension) < errorThreshold)
return;
float scalingFactor = desiredDimension / imageDimension;
scalingFactor = (float)(Math.floor(scalingFactor * 100) * 0.01f);
replaceImage(ImageUtilities.getScaledImage( image, scalingFactor, scalingFactor));
}
public synchronized void rotate(int degrees) {
replaceImage(ImageUtilities.getRotatedImage( image, degrees));
}
private void replaceImage(RenderedOp newImage) {
image.dispose();
System.gc();
image = newImage;
}
© Sioux 2012 | Confidential | 22
Magic numbers
 Every number is a magic number
 Replace it with a named constant
© Sioux 2012 | Confidential | 23
double circumference = radius * Math.PI * 2;
if (password.length() > 7)
public static final int MAX_PASSWORD_SIZE = 7;
if (password.length() > MAX_PASSWORD_SIZE)
Applying clean code
 Know how to write clean code
 Think about these small improvements
during:
o New development
o Code reviews
o Changing code
o Fixing bugs
 So code will be easier to understand and
cheaper to modify
© Sioux 2012 | Confidential | 24
Conclusion
Always code as if the guy who ends up
maintaining your code will be a
violent psychopath who knows where you live.
Code for readability.
© Sioux 2012 | Confidential | 25
Questions?
© Sioux 2012 | Confidential | 26
27© Sioux 2012 | Confidential |
roy.nitert@sioux.eu
+31 (0)40 2677100

More Related Content

Similar to Clean code

MuleSoft London Community February 2020 - MuleSoft and OData
MuleSoft London Community February 2020 - MuleSoft and ODataMuleSoft London Community February 2020 - MuleSoft and OData
MuleSoft London Community February 2020 - MuleSoft and ODataPace Integration
 
CDI, Seam & RESTEasy: You haven't seen REST yet!
CDI, Seam & RESTEasy: You haven't seen REST yet!CDI, Seam & RESTEasy: You haven't seen REST yet!
CDI, Seam & RESTEasy: You haven't seen REST yet!Dan Allen
 
Import web resources using R Studio
Import web resources using R StudioImport web resources using R Studio
Import web resources using R StudioRupak Roy
 
RESTful application with JAX-RS and how to expose and test them
RESTful application with JAX-RS and how to expose and test themRESTful application with JAX-RS and how to expose and test them
RESTful application with JAX-RS and how to expose and test themKumaraswamy M
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)James Titcumb
 
JavaOne 2009 - TS-5276 - RESTful Protocol Buffers
JavaOne 2009 - TS-5276 - RESTful  Protocol BuffersJavaOne 2009 - TS-5276 - RESTful  Protocol Buffers
JavaOne 2009 - TS-5276 - RESTful Protocol BuffersMatt O'Keefe
 
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and MonitoringInnovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and MonitoringCary Millsap
 
Mock Servers - Fake All the Things!
Mock Servers - Fake All the Things!Mock Servers - Fake All the Things!
Mock Servers - Fake All the Things!Atlassian
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Javaelliando dias
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)James Titcumb
 
Mind Your Business. And Its Logic
Mind Your Business. And Its LogicMind Your Business. And Its Logic
Mind Your Business. And Its LogicVladik Khononov
 
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaSolutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaGuido Schmutz
 
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...jpalley
 
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache KafkaSolutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache KafkaGuido Schmutz
 
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...confluent
 
OpenERP e l'arte della gestione aziendale con Python
OpenERP e l'arte della gestione aziendale con PythonOpenERP e l'arte della gestione aziendale con Python
OpenERP e l'arte della gestione aziendale con PythonPyCon Italia
 
Boost Your Neo4j with User-Defined Procedures
Boost Your Neo4j with User-Defined ProceduresBoost Your Neo4j with User-Defined Procedures
Boost Your Neo4j with User-Defined ProceduresNeo4j
 
Data models in Angular 1 & 2
Data models in Angular 1 & 2Data models in Angular 1 & 2
Data models in Angular 1 & 2Adam Klein
 
Consuming Data From Many Platforms: The Benefits of OData - St. Louis Day of ...
Consuming Data From Many Platforms: The Benefits of OData - St. Louis Day of ...Consuming Data From Many Platforms: The Benefits of OData - St. Louis Day of ...
Consuming Data From Many Platforms: The Benefits of OData - St. Louis Day of ...Eric D. Boyd
 

Similar to Clean code (20)

REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Java
 
MuleSoft London Community February 2020 - MuleSoft and OData
MuleSoft London Community February 2020 - MuleSoft and ODataMuleSoft London Community February 2020 - MuleSoft and OData
MuleSoft London Community February 2020 - MuleSoft and OData
 
CDI, Seam & RESTEasy: You haven't seen REST yet!
CDI, Seam & RESTEasy: You haven't seen REST yet!CDI, Seam & RESTEasy: You haven't seen REST yet!
CDI, Seam & RESTEasy: You haven't seen REST yet!
 
Import web resources using R Studio
Import web resources using R StudioImport web resources using R Studio
Import web resources using R Studio
 
RESTful application with JAX-RS and how to expose and test them
RESTful application with JAX-RS and how to expose and test themRESTful application with JAX-RS and how to expose and test them
RESTful application with JAX-RS and how to expose and test them
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 
JavaOne 2009 - TS-5276 - RESTful Protocol Buffers
JavaOne 2009 - TS-5276 - RESTful  Protocol BuffersJavaOne 2009 - TS-5276 - RESTful  Protocol Buffers
JavaOne 2009 - TS-5276 - RESTful Protocol Buffers
 
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and MonitoringInnovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and Monitoring
 
Mock Servers - Fake All the Things!
Mock Servers - Fake All the Things!Mock Servers - Fake All the Things!
Mock Servers - Fake All the Things!
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Java
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
Mind Your Business. And Its Logic
Mind Your Business. And Its LogicMind Your Business. And Its Logic
Mind Your Business. And Its Logic
 
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache KafkaSolutions for bi-directional integration between Oracle RDBMS & Apache Kafka
Solutions for bi-directional integration between Oracle RDBMS & Apache Kafka
 
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
RailsConf 2010: From 1 to 30 - How to refactor one monolithic application int...
 
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache KafkaSolutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
Solutions for bi-directional Integration between Oracle RDMBS & Apache Kafka
 
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
Solutions for bi-directional integration between Oracle RDBMS and Apache Kafk...
 
OpenERP e l'arte della gestione aziendale con Python
OpenERP e l'arte della gestione aziendale con PythonOpenERP e l'arte della gestione aziendale con Python
OpenERP e l'arte della gestione aziendale con Python
 
Boost Your Neo4j with User-Defined Procedures
Boost Your Neo4j with User-Defined ProceduresBoost Your Neo4j with User-Defined Procedures
Boost Your Neo4j with User-Defined Procedures
 
Data models in Angular 1 & 2
Data models in Angular 1 & 2Data models in Angular 1 & 2
Data models in Angular 1 & 2
 
Consuming Data From Many Platforms: The Benefits of OData - St. Louis Day of ...
Consuming Data From Many Platforms: The Benefits of OData - St. Louis Day of ...Consuming Data From Many Platforms: The Benefits of OData - St. Louis Day of ...
Consuming Data From Many Platforms: The Benefits of OData - St. Louis Day of ...
 

Recently uploaded

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 

Recently uploaded (20)

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 

Clean code

  • 2. Clean code agenda  Quality  Readability  Code smells  Clean code characteristics  Single responsibility principle  Code comments  Small methods  Descriptive names  Applying clean code © Sioux 2012 | Confidential | 2
  • 3. Quality  Poor SW quality cost $500 billion per year  Customer expectation, free of deficiencies, easy to use  Improve quality: testing, requirements, documentation, code reviews  Studies have shown that poor readability correlates strongly with defect density. © Sioux 2012 | Confidential | 3
  • 4. Requirements © Sioux 2012 | Confidential | 4
  • 5. Readability  To make it easier to understand and cheaper to modify (maintainability) software  The code you write will be read more times than it was written and by more people.  “Any fool can write code that a computer can understand. Good programmers write code that humans can understand.” - Martin Fowler © Sioux 2012 | Confidential | 5
  • 6. Recognizing clean code © Sioux 2012 | Confidential | 6
  • 7. Code smells  A „smell‟ in code is a hint that something might be wrong with the code  Duplicated code  Long switch/if statements  Long methods  Poor method/variable names  In-line comments  Large classes © Sioux 2012 | Confidential | 7
  • 8. What is clean code ? Characteristics of clean code:  Small methods and classes  Descriptive names  Not too many parameters in methods (and no flags)  No obvious or irrelevant comments (code must be self describing)  No redundancy (DRY: don‟t repeat yourself)  No magic numbers  Single responsibility principle (SRP)  Uniform coding style © Sioux 2012 | Confidential | 8
  • 9. SRP: Single Responsibility Principle  every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class.  a class or module should have one, and only one, reason to change  If class names have „manager‟ or „processor‟ in them, they probably have multiple responsibilities  the "S" in "SOLID" stands for the single responsibility principle (“Principles Of OOD”, Robert C. Martin) © Sioux 2012 | Confidential | 9
  • 10. Comments © Sioux 2012 | Confidential | 10
  • 11. Comments  Comments do not make up for bad code  Good: Legal, explanation, TODO  Bad: redundant, misleading, journal, headers  Don‟t use a comment when you can use a function or a variable © Sioux 2012 | Confidential | 11 // Returns an instance of the Responder being tested. protected abstract Responder responderInstance(); protected abstract Responder responderBeingTested();
  • 12. Small methods © Sioux 2012 | Confidential | 12  They should be very very small  Should do one thing, do it well, do it only  One level of abstraction  Should read like a narrative  Should not have sections  Blocks within if, else and while statements should be one line long
  • 13. /*---------------------------------------------------------------------------*/ int PO_rq_do_service( PO_object_t *object_p, DDXA_var_string_t *document_type, DDXA_var_string_t *service, DDXA_var_string_t *document_path, DDXA_var_string_t *input_file_path, DDXA_var_string_t *output_file_path, ASML_bool use_compression, PLXAtimestamp *time_stamp, POXA_var_string_array_t *parameters, DDXA_var_string_t *user_name, POXA_DocMetaDataListType *list, POXA_var_string_array_t *error_messages ) /* * Description : Execute the requested service. The requested service is specified in * the 'service' parameter. The following services are defined: * put (=download), get (=upload), list, verify, and delete). * * Input(s) : document_type - type of document ( e.g. ADELfoo ) * service - Name of the service (get, put, verify, delete, list) * document_path - Service = get, delete, list: * Document identification (e.g. path/to/folder/foo.xml) * - Service = put, verify: * Not used. * input_file_path - Service = put, verify: * Name of XML formatted file (path+name) * - Service = get, delete, list * Not used. * output_file_path - Service = put, verify * Name of the XML formatted report file (path+name) * - Service = get * Name of the XML formatted file (path+name) * - Service = list * Name of the XML formatted ADELdirectory file (path+name) * (for Y* components using generic POxSERVICE interface) * - Service = delete * Not used * use_compression - Flag to indicate incoming document must unzipped and/or * outgoing document must be zipped. * time_stamp - Service = get * Time stamp of subrecipe to get (optional). * Service = put, verify, delete, list * Not used. * parameters - Array of strings pairs containing all the options and * values from the URL query string. * user_name - Name of an authenticated user * * Output(s) : list - Service = list * List of document names found, including meta data (used * for old Y* components NOT using generic POxSERVICE * interface) * - Service = put, get, verify, delete * Not used * error_messages - Array of error messages. * * Returns : OK * POXA_PARAM_ERR; * POXA_INVALID_TYPE; * POXA_ERR_RECIPE_DOES_NOT_EXIST; * POXA_SYS_ERR; * * Notes : The implementation of this function will have the following limitations: * - UserName: The UserName will be used for a user authorization mechanism. * This mechanism will not be implemented, the parameter will be ignored. * - ErrorMessages: The array of error messages will remain empty. * * Pre.Cond. : * * Post.Cond. : */ { int r = OK; int r_unzip = OK; ASML_bool single_zip = FALSE; ASML_bool is_secs = FALSE; POXA_DataType data_type = POXA_DATA_TYPE_UNDEFINED; PODS_SERVICE_ENUM service_value = PODS_SERVICE_UNKNOWN; char type_name[PODS_MAX_TYPE_LENGTH] = ""; if (( r == OK) && (object_p == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, object_p = NULL")); } if (( r == OK) && (document_type == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, document_type = NULL")); } if (( r == OK) && (service == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, service = NULL")); } if (( r == OK) && (document_path == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, document_path = NULL")); } if (( r == OK) && (input_file_path == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, input_file_path = NULL")); } if (( r == OK) && (output_file_path == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, output_file_path = NULL")); } if ((r == OK) && (time_stamp == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, time_stamp = NULL")); } if (( r == OK) && (parameters == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, parameters = NULL")); } if (( r == OK) && (user_name == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, user_name = NULL")); } if (( r == OK) && (list == NULL)) { r = PO_ERR_NULL_PARAMETER; ERXA_LOG(r, OK, ("Parameter Error, list = NULL")); } if (( r == OK) && (error_messages == NULL)) { r = PO_ERR_NULL_PARAMETER; © Sioux 2012 | Confidential | 13 Long function if ( (r == OK) && ( strcmp( document_type->buf, "" ) == 0 ) ) { is_secs = TRUE; } if (r == OK) { THXAtrace (CC, THXA_TRACE_INT, __func__, "> (%D, %D, %D, %D, %D, use_compression=%s, %D, %D, %D)", "document_type", "varstring", document_type, "service", "varstring", service, "document_path", "varstring", document_path, "input_file_path", "varstring", input_file_path, "output_file_path", "varstring", output_file_path, (use_compression) ? "yes" : "no", "time_stamp", "timestamp", time_stamp, "parameters", POXA_VAR_STRING_ARRAY_T_STR, parameters, "user_name", "varstring", user_name ); } if (r == OK) { if ( strcmp(service->buf, POXA_SERVICE_GET_STRING) == 0 ) { if ( data_type == POXA_DATA_TYPE_FILE ) { service_value = PODS_SERVICE_GET_FILE_PATH; } else { service_value = PODS_SERVICE_GET; } } else if ( strcmp(service->buf, POXA_SERVICE_PUT_STRING) == 0 ) { service_value = PODS_SERVICE_PUT; } else if ( strcmp(service->buf, POXA_SERVICE_VERIFY_STRING) == 0 ) { service_value = PODS_SERVICE_VERIFY; } else if ( strcmp(service->buf, POXA_SERVICE_DELETE_STRING) == 0 ) { service_value = PODS_SERVICE_DELETE; } else if ( strcmp(service->buf, POXA_SERVICE_LIST_STRING) == 0 ) { service_value = PODS_SERVICE_LIST; } else { service_value = PODS_SERVICE_UNKNOWN; } } if (r == OK) { if ( ( service_value == PODS_SERVICE_PUT) || ( service_value == PODS_SERVICE_VERIFY) ) { /* If compressed file sent source_xml_filename contains the filename of * xml document and can be anything. Type of document must be retreived * from the contents of the document itself. * In case a multi zip file is in the input_file, this call * will result in NOK, thereforeresult is directed to different result * variable (r_unzip) */ if ( is_secs ) { if ( use_compression ) { r_unzip = POGN_unzip_file( input_file_path->buf ); if (r_unzip == OK) { single_zip = TRUE; } } /* Get document type from the file. */ r = PODS_get_type_from_doc_file( input_file_path->buf, type_name ); if (r == OK) { r = DDXA_var_string_alloc( document_type, type_name ); } /* Incase of unzip the file will need to be zipped */ if ( single_zip ) { r_unzip = POGN_zip_file( input_file_path->buf ); } } } else if ( (service_value == PODS_SERVICE_LIST) || (service_value == PODS_SERVICE_GET) || (service_value == PODS_SERVICE_GET_FILE_PATH) || (service_value == PODS_SERVICE_DELETE) ) { if ( is_secs ) { /* 'document_type' is empty string -> Document is sent via SX. */ r = PODS_extract_type_from_doc_id( document_path->buf, type_name ); if (r == OK) { r = DDXA_var_string_cat( document_type, type_name ); } else { ERXA_LOG(PO_ERR_SYS_ERROR, r, ("Error: Cannot extract document type and path from'%s'", document_path->buf)); r = PO_ERR_SYS_ERROR; } } } else { ERXA_DEACT( OK, PO_ERR_SYS_ERROR, ( "Unknown service requested." ) ); } } if ( r == OK ) { if ( (service_value == PODS_SERVICE_GET) || (service_value == PODS_SERVICE_GET_FILE_PATH) ) { r = po_rq_handle_service_get( PO_RQ_ACTION_UPLOAD, document_type, document_path, input_file_path, output_file_path, time_stamp, parameters); } else if ( service_value == PODS_SERVICE_PUT ) { r = po_rq_handle_service_put_verify( PO_RQ_ACTION_DOWNLOAD, document_type, input_file_path, /*---------------------------------------------------------------------------*/ PO_RQ_ACTION_DOWNLOAD, document_type, input_file_path, output_file_path, use_compression, parameters, TRUE, single_zip); } else if ( service_value == PODS_SERVICE_VERIFY ) { r = po_rq_handle_service_put_verify( PO_RQ_ACTION_VERIFY, document_type, input_file_path, output_file_path, use_compression, parameters, FALSE, single_zip); } else if ( service_value == PODS_SERVICE_DELETE ) { r = po_rq_handle_service_delete( document_type, document_path, input_file_path, parameters); } else if ( service_value == PODS_SERVICE_LIST ) { r = po_rq_handle_service_list( document_type, document_path, parameters, output_file_path, list); } else { r = PO_ERR_SYS_ERROR; ERXA_LOG(r, OK, ("Error: unsupported service '%s'", service->buf)); } } /* Zip the target file if necessary (put, verify and get). */ if ( ( r == OK ) && use_compression && ( ( service_value == PODS_SERVICE_GET ) || ( service_value == PODS_SERVICE_GET_FILE_PATH ) || ( service_value == PODS_SERVICE_PUT ) || ( service_value == PODS_SERVICE_VERIFY ) ) ) { if (single_zip) { r = POGN_zip_file(output_file_path->buf); } } /* create POXA errorcode from internal error codes */ if (r != OK) { int l = r; int r_pr = OK; char message[ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE]= ""; /* createPOXA errorcode frominternal error codes */ switch (l) { case PO_ERR_NULL_PARAMETER: r = POXA_PARAM_ERR; r_pr = PLXAstr_strlcpy(message, "NULL parameter passed.", ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE); break; case PO_ERR_INVALID_TYPE: r = POXA_INVALID_TYPE; r_pr = PLXAstr_snprintf(message, ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE, "Invalid type '%s' provided.", document_type->buf); break; case PO_ERR_NO_INSTANCE_ID_FOUND: case PO_ERR_OPENING_FILE: r = POXA_ERR_RECIPE_DOES_NOT_EXIST; r_pr = PLXAstr_snprintf(message, ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE, "File '%s' does not exist.", input_file_path->buf); break; case PO_ERR_GETTING_LIST: case PO_ERR_GETTING_DATA: case PO_ERR_STORING_DATA: case PO_ERR_PUTTING_DATA: case PO_ERR_VERIFYING_DATA: case PO_ERR_DELETING_DATA: r = POXA_SERVICE_FAILED; r_pr = PLXAstr_snprintf(message, ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE, "Service '%s' failed for document type '%s'.", service->buf, document_type->buf); break; case PO_ERR_SYS_ERROR: default: r = POXA_SYS_ERR; r_pr = PLXAstr_strlcpy(message, "Internal error occurred.", ADELserviceResponse_MAX_MESSAGE_TYPE_SIZE); break; } if (r_pr == OK) { if ( ( !is_secs ) && ( strcmp( output_file_path->buf, "" ) != 0) ) { int r_csr = OK; r_csr = po_rq_create_service_response(output_file_path->buf, ADELserviceResponse_Error, r, message); if (r_csr != OK) { ERXA_DEACT( POXA_SYS_ERR, r_csr, ("") ); } } } else { ERXA_DEACT( POXA_SYS_ERR, r_pr, ("") ); } ERXA_LOG(r, l, PO_RQ_ACTION_DOWNLOAD, ("Error: Execution of service '%s' with document_type '%s' failed", service->buf, document_type->buf) ); } THXAtrace (CC, THXA_TRACE_INT, __func__, "< (%D, %D) = %R", "list", POXA_DOCMETADATALISTTYPE_STR, list, "error_messages", POXA_VAR_STRING_ARRAY_T_STR, error_messages, r); return r; }
  • 14. Descriptive names © Sioux 2012 | Confidential | 14  Names make software readable  Helps clarify the design in your mind  Use long names for long scopes  Avoid encodings
  • 15. Descriptive names example Public int x() { int q = 0; int z = 0; for (int kk = 0; kk < 10; kk++) { if (l[z] == 10) { q += 10 + (l[z + 1] + l[z + 2]); z += 1; } else if (l[z] + l[z + 1] == 10) { q += 10 + l[z + 2]; z += 2; } else { q += l[z] + l[z + 1]; z += 2; } } return q; } © Sioux 2012 | Confidential | 15
  • 16. Descriptive names example Public int score() { int score = 0; int frame = 0; for (int frameNumber = 0; frameNumber < 10; frameNumber++) { if (isStrike(frame)) { score += 10 + nextTwoBallsForStrike(frame); frame += 1; } else if (isSpare(frame)) { score += 10 + nextBallForSpare(frame); frame += 2; } else { score += TwoBallsInFrame(frame); frame += 2; } } return score; } © Sioux 2012 | Confidential | 16
  • 17. Parameters / arguments © Sioux 2012 | Confidential | 17  Small number: Zero is best, followed by one, two or three  More than three is questionable  Output arguments are counterintuitive  Boolean arguments (flags) loudly declare than the function does more than one thing  Simpler is easy to understand and easy to test  Reduce number of arguments by creating objects out of them
  • 18. Parameters example Circle makeCircle(double x, double y, double radius); public void AlignTaskCanBeStopped(bool useRealXps); AlignTaskCanBeStopped(true); © Sioux 2012 | Confidential | 18
  • 19. Parameters example Circle makeCircle(Point center, double radius); public void AlignTaskCanBeStoppedWith RealXps(); public void AlignTaskCanBeStoppedWith SimulatedXps(); © Sioux 2012 | Confidential | 19
  • 20. Don‟t repeat yourself © Sioux 2012 | Confidential | 20  Duplication  DRY principle (Dave Thomas)  Once, and only once (Kent Beck)  Duplication is a missed opportunity for abstraction  Examples: o Identical code (copy/paste) o Switch/case (or if/else) chains o Similar algorithms  Design patterns and OO itself are strategies for eliminating duplication
  • 21. DRY example public void scaleToOneDimension( float desiredDimension, float imageDimension) { if (Math.abs(desiredDimension – imageDimension) < errorThreshold) return; float scalingFactor = desiredDimension / imageDimension; scalingFactor = (float)(Math.floor(scalingFactor * 100) * 0.01f); RenderOp newImage = ImageUtilities.getScaledImage( image, scalingFactor, scalingFactor); image.dispose(); System.gc(); image = newImage; } public synchronized void rotate(int degrees) { RenderOp newImage = ImageUtilities.getRotatedImage( image, degrees); image.dispose(); System.gc(); image = newImage; } © Sioux 2012 | Confidential | 21
  • 22. DRY example public void scaleToOneDimension( float desiredDimension, float imageDimension) { if (Math.abs(desiredDimension – imageDimension) < errorThreshold) return; float scalingFactor = desiredDimension / imageDimension; scalingFactor = (float)(Math.floor(scalingFactor * 100) * 0.01f); replaceImage(ImageUtilities.getScaledImage( image, scalingFactor, scalingFactor)); } public synchronized void rotate(int degrees) { replaceImage(ImageUtilities.getRotatedImage( image, degrees)); } private void replaceImage(RenderedOp newImage) { image.dispose(); System.gc(); image = newImage; } © Sioux 2012 | Confidential | 22
  • 23. Magic numbers  Every number is a magic number  Replace it with a named constant © Sioux 2012 | Confidential | 23 double circumference = radius * Math.PI * 2; if (password.length() > 7) public static final int MAX_PASSWORD_SIZE = 7; if (password.length() > MAX_PASSWORD_SIZE)
  • 24. Applying clean code  Know how to write clean code  Think about these small improvements during: o New development o Code reviews o Changing code o Fixing bugs  So code will be easier to understand and cheaper to modify © Sioux 2012 | Confidential | 24
  • 25. Conclusion Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability. © Sioux 2012 | Confidential | 25
  • 26. Questions? © Sioux 2012 | Confidential | 26
  • 27. 27© Sioux 2012 | Confidential | roy.nitert@sioux.eu +31 (0)40 2677100

Editor's Notes

  1. SW designer, 37y, married, 2 doughters. 12y graduated Twente, EE. 5y Philips CE and semi. 7y Sioux, worked for Philips HC, FEI and ASML.Write code in C, C++, C#, bit of Java and Python, and modelling in ASD.Are you programmers ? Ever heard of clean code ? Know the book ?
  2. 500 billion: Bron: http://www-03.ibm.com/software/products/us/en/category/SW730http://en.wikipedia.org/wiki/Software_qualityStudies: http://www.computer.org/csdl/trans/ts/2010/04/tts2010040546-abs.htmlCode that’s difficult to read tends to be difficult to test, too, which leads to fewer tests being written.
  3. A software program will have, on average, 10 generations of maintenance programmers in its lifetime.Communication : So to minimize the cost of maintenance, your code should be clear to those people (or yourself) reading it a later date. It should be nice to read, it should clearly communicate its design, and it should not be overly complex.
  4. From the book Clean code by Robert Martin.
  5. By Kent Beck
  6. Clean code – A Handbook of Agile Software Craftsmanship – Robert MartinStyle -&gt; indenting
  7. SOLID: SRP, OCP, LSP, DIP, ISP
  8. Comments were considered good programming practice
  9. Comments chapter from Clean code bookDon’t use comments to describe code. . Only use comments when the code can not tell it.
  10. Func 150-500 -&gt; 5-20File 1000-5000 -&gt; 100-500Use extract method to make it smaller
  11. For loop can have a inti as variable, when the scope is smallEncodings: it should read well (don’t abbriviate). Also don’t use hungarian notation etc. (http://en.wikipedia.org/wiki/Hungarian_notation)
  12. Two/three: ordering of arguments is a problem. =&gt; mix upassertEquals(expected, actual);Flag: the call is confusing ! =&gt; split it up
  13. Duplication is a problem for maintenance. You have to remember to change it in multiple locationsBeck (XP)Also Ron Jeffries says it is the second most important rule, just after getting the tests to passSwitch/case can be solved with polymorphismsDuplication is one of the big code smells that prgrammers have to solve
  14. Easy: 3 lines of identical code=&gt; Create new method
  15. Higher level of abstraction: new method name describing what it doesTotal is 1 line less code
  16. Every time you have an opportunity to change code, make sure it is a little cleaner.Boy scout rule: leave the campground a little cleaner than when you found it.
  17. Motivator by John F Woods in 1991 (on the subject of using the comma operator)