Skip to content

Instantly share code, notes, and snippets.

@fxfabre
Created November 12, 2018 17:40
Show Gist options
  • Save fxfabre/b02f294c990176050f1d62d90f4b9d85 to your computer and use it in GitHub Desktop.
Save fxfabre/b02f294c990176050f1d62d90f4b9d85 to your computer and use it in GitHub Desktop.

Clean Code: A Handbook of Agile Software Craftsmanship

In software, 80% of time = maintenance
1951, Total productive maintenance (TPM), fondations du Lean management

5 S principes, piliers du TPM :

  • Sort : knowing where things are : good names for identifiers
  • Systemize : A piece of code should be where you expect to find it
  • Cleaning : Remove commented code that 'may' be usefull for the future
  • Standardization : consistant coding style and practices in the dev team
  • Discipline : follow the practices

C'est la responsabilité du développeur d'expliquer au manager les contraintes qu'il a, et l'impact de l'architecture sur le besoin business. Ainsi que préciser, clarifier les demandes business et leur impact sur la complexité du programme.
1 method (function) says what it does, sub-methods say how it is done
An object do 1 thing.

During development, we spend more than 90% of time reading code.
Easy to read => saved time and easier to write

SRP : Single responsability principle
OCP : Open close principle
DIP : Dependency inversion principle

Naming variables, functions, classes

  • If a name require a comment, then the name does not reveal its intent.
  • Avoid disinformation : AccountList must be a list. Otherwise, use accounts.
  • If names must be different, they should mean something different.
  • Avoid meaningless / noise words like info, data, the, variable, table, ... Ex : nameString -> name, customerObject -> customer, productData -> product ...
  • Use pronounceable words : gen_ymdhms -> generationTimestamp
  • Use searchable names : a variable named 'e' can't be found easily with a search. Give a name to constants, to be able to find the others usages of this constant => quite long names are good.
  • The length of a name should correspond to the size of its scope.
  • Don't put the type in the variable name. Name won't change if you change the type.
  • A class name should not be a verb. Avoid Processor, Manager, Data, Info in class name.
  • Methods should have a verb in their names : DeletePage, Save ... + use get, set, is
  • For constructors, use static factory methods : Complex.FromRealNumber(12) instead of new Complex(12)
  • Pick one word per concept : don't mix fetch, retrieve and get, Controller & Manager

Functions should :

  • be from 2 to 10 lines long
  • Do one thing
  • Be 1 level of abstraction below function name

Switch statement :

  • Should appear only once
  • Should be used only to create polymorphic object (abstract factory)

Le cerveau sait manipuler quelques objets complexes / abstraits facilement.
L'ordinateur sait manipuler beaucoup d'objets simples facilement.
=> Il faut apprendre a faire le lien entre les 2

In objects, avoid output arguments. this / self is the output.

Functions should either do something or answer something. Not both
-> Use exceptions instead of error code.
Extract the body of a try to a function : otherwise mix error processing with normal processing.

Comments are to compensate our failure to express ourself in code.
Inaccurate comments are worse than no comment at all
Don't use a comment when you can use a function or variable.
Don't comment code. Source control can remember old code.

Code formatting :

  • Les fonctionnalités changent souvent, mais la lisibilité a un impact sur toute la vie de l'application.
  • Concepts les plus gros en haut du fichier source, les détails les plus fins en bas.

Programmation object vs procédurale.

Prog procédurale :

Struct Square:
	Point topLeft
	double side
	
Struct Rectangle:
	Point topLeft
	double width
	double height

def getArea(shape):
	if shape is Rectangle:
		return shape.width * shape.height
	return shape.side ** 2
  • Easy to add new function : eg getPerimeter
  • Hard to add new fields(2D -> 3D) or to add a new data structure (Circle, triangle ...) => Need to update many functions (getArea, getPerimeter, ...)

Prog objet

class Square (Shape):
	Point topLeft
	double side
	double getArea() { return side ** 2}
	
class Rectangle(Shape):
	point topLeft
	double width, height
	double getArea() { return width * height}

Oo programming:

  • Hard to add a new function : must update all data structures.
  • Easy to add a new field or a new data structure.

=> The things that are hard for OO are easy for procedures.
=> Simple data structures, without objects, can be usefull

  • With data structures, can do dataStructure.field1.field2.field3
  • With objects : can do object.f(), don't do object.f().g()

Gestion d'erreurs

Ne pas renvoyer Null, mais liste vite ou élément neutre ou Exception.
=> Evite de complexifier le code avec des if (isNull)
=> Evite des NullPointerException

Wrapper une API qui renvoie du Null

Ne pas passer Null a une fonction.

Références externes

https://medium.com/coding-skills/clean-code-101-meaningful-names-and-functions-bf450456d90c

http://www.inf.fu-berlin.de/inst/ag-se/teaching/K-CCD-2014/Clean-Code-summary.pdf

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment