Buenas prácticas en el desarrollo de software

Piero Divasto

M.Sc. in Business Informatics

Team Lead & Full-stack Developer @ Nisum

Lead de Facebook Developers Circle: Santiago

Agenda

Buenas prácticas

Git

Código

Agile

Conclusiones

Git

Buenas prácticas

http://nvie.com/posts/a-successful-git-branching-model/

Feature Branch Architecture

Git

Buenas prácticas

feature/story

pull request

develop
master

Git

Buenas prácticas

PRO-123
develop

Código story + nombre de story

$ git checkout -b PRO-123

Git

Buenas prácticas

PRO-123
develop

PULL REQUEST!

Git

Buenas prácticas - Pull Request

Instancia importante

Momento para hacer peer-review

Otro miembro del equipo inspecciona el código y hace comentarios

Verificar si realmente la tarea esta lista (definition of done), verificar coding style, tests, etc.

También eres responsable de lo que se acepta!

Git

Buenas prácticas - Destruir feature branches

PRO-123
develop
PRO-124

Destruir branch después de hacer PR! No más commits!

Git

Buenas prácticas - Destruir feature branches

PRO-123
develop
PRO-124
PRO-124-CONT

Git

Buenas prácticas - Rebase

PRO-123
develop
PRO-124
PRO-124
$ git checkout PRO-124
$ git rebase develop

Git

Buenas prácticas - Multiples devs p/feature

PRO-123
develop
PRO-124
feature
PRO-124
$ git checkout PRO-124
$ git rebase feature

Git

Buenas prácticas - Commits

Explica lo que hiciste (Problema + solución)

Título no más de 50 caracteres

Titulo + Comentario

En PR incluir código y titulo de story

PRO-123: Titulo del story/task

Git

Buenas prácticas - Conclusión

Un/a dev por feature branch

Merge siempre y cuando no rompa algo

Pull request => IMPORTANTE!

Rebase! (historial mucho mas limpio)

hotfixes en                 

master

Git

Buenas prácticas - Referencias

https://speakerdeck.com/ewoodh2o/release-management-git-workflow
http://nvie.com/posts/a-successful-git-branching-model/
https://www.youtube.com/watch?v=qyz3jkOBbQY

How GitHub Uses GitHub to Build GitHub by Zach Holman

Código

Buenas prácticas

Código

Buenas prácticas

“Try and leave this world a little better than you found it . . .”

Robert Stephenson Smyth Powell

Código

Buenas prácticas - Principios

SOLID

DRY

Código

Buenas prácticas - SOLID

Single Reponsibility Principle

Open Closed Principle

Liskov Substitution Principle

Interface Segregation Principle

Dependency Inversion

Código

Buenas prácticas - Single Responsibility Principle

Código

Buenas prácticas - Single Responsibility Principle

class Book_NoSRP {
    public String Author { get; set; }
    public String Title { get; set; }
    public void save() {
        //Save to database code.
        //Open db connection.
        //Make some logic checks.
        //DB CRUD operations.
        //Close connection.
    }
}
class Book_SRP {
    public String Author { get; set; }
    public String Title { get; set; }
}

class PersistenceService {
    public void save(Book_SRP bookToSave) {
        //Save to database code.
        //Open db connection.
        //DB CRUD operations.
        //Close connection.
    }
}
https://dzone.com/articles/solid-principles-by-examples-single-responsability?fromrel=true

Código

Buenas prácticas - Open Closed Principle

public class HumanResourceDepartment {
    private List<FrontEndDev> hiredFrontEndDevs;
    private List<BackEndDev> hiredBackEndDevs;    
    public void hire(FrontEndDev frontEndDev){ 
        frontEndDevs.signContract();
        hiredDevs.add(frontEndDev);
    }
    public void hire(BackEndDeveloper backEndDevs){ 
        backEndDevs.signContract();
        hiredBackEndDevs.add(backEndDev);
    }
}
https://dzone.com/articles/solid-principles-by-examples-openclosed?fromrel=true

"An object/entity should be open for extension but closed for modification."

interface Employee { public void SignContract(); }
class FrontEndDev implements Employee {
    public void signContract() { //... }
}
class BackEndDev extends Employee {
    public void signContract() { //... }
}
class FullStackDev extends Employee {
    public void signContract() { //... }
}
public class HumanResourceDepartment {
    private List<Employee> employees;
    public void hire(Employee employee) {
        employee.signContract();
        employees.add(employee);
    }
}

Código

Buenas prácticas - Liskov Substitution Principle

https://dzone.com/articles/solid-principles-by-examples-liskov-substitution-p

"Let q(x) be a property provable about objects x of type T. Then q(y) should be provable for objects y of type S where S is a subtype of T."  Barbara Liskov

Una subclase debe sobre-escribir un método del padre siempre y cuando no rompa la funcionalidad desde el punto de vista del consumidor.

Código

Buenas prácticas - Liskov Substitution Principle

https://dzone.com/articles/solid-principles-by-examples-liskov-substitution-p
abstract class MusicalInstrument {
    public void playNote();
}

class Piano extends MusicalInstrument {
    public void playNote() {
        pressKey();
    }
    private void pressKey() {
        // Press a piano key.
    }
}

class Saxophone extends MusicalInstrument {
    public void playNote() {
        blow();
    }
    private void blow() {
        //Blow air into the instrument.
    }
}

Código

Buenas prácticas - Liskov Substitution Principle

https://dzone.com/articles/solid-principles-by-examples-liskov-substitution-p
class Rectangulo {
    private int ancho;
    private int alto;

    // setter & getter
    
    public int area() { return ancho * alto; }
}

class Cuadrado extends Rectangulo {
    @Overrride public void setAncho(int ancho) {
        this.ancho = ancho;
        this.alto = ancho;
    }
    
    @Override public void setAlto(int alto) {
        this.ancho = alto;
        this.alto = alto;
    }
}
abstract class Figura {
    public int area();
}

class Rectangulo extends Figura {
    private int ancho;
    private int alto;

    @Override
    public int area() { return ancho * alto; }
}

class Cuadrado extends Figura {
    private int lado;

    @Override
    public int area() { return lado * lado; }
}

Código

Buenas prácticas - Interface Segregation Principle

interface SmartDevice {
    void print();
    void fax();
    void scan();
}

class AllInOnePrinter implements SmartDevice {
    public void print() { // Printing code. }
    public void fax() { // Beep booop biiiiip. }
    public void scan() { // Scanning code. }
}

class NormalPrinter implements SmartDevice {
    public void print() { // Printing code. }
    public void fax() { 
        throw new NotSupportedException(); 
    }
    public void scan() { 
        throw new NotSupportedException(); 
    }
}
interface Printer {
    void print();
}

interface Fax {
    void fax();
}

interface Scanner {
    void scan();
}

class AllInOnePrinter implements Printer, Fax, Scanner {
    public void print() { // Printing code. }
    public void fax() { // Beep booop biiiiip. }
    public void scan() { // Scanning code. }
}

class NormalPrinter implements Printer {
    public void print() { // Printing code. }
}

"The interface-segregation principle (ISP) states that no client should be forced to depend on methods it does not use."

https://dzone.com/articles/solid-principles-by-example-interface-segregation

Código

Buenas prácticas - Dependency Inversion

https://dzone.com/articles/solid-principles-by-example-dependency-inversion

The principle states:

  1. High-level modules should not depend on low-level modules. Both should depend on abstractions.
  2. Abstractions should not depend on details. Details should depend on abstractions.

Código

Buenas prácticas - Dependency Inversion

https://dzone.com/articles/solid-principles-by-example-dependency-inversion
 class Logger {
    private NtfsFileSystem fileSystem = new NtfsFileSystem();

    public void log(String text) {
        var fileStream = fileSystem.openFile("log.txt");
        fileStream.write(text);
        fileStream.dispose();
    }
}

Y si cambia la implementación/versión de NtfsFileSystem?

Código

Buenas prácticas - Dependency Inversion

https://dzone.com/articles/solid-principles-by-example-dependency-inversion
interface Loggable {
    void log(String textToLog);
}

class NtfsFileSystem implements Loggable {
    public void log(String textToLog) {
        //file handling, writing and disposing.
    }
}

class Logger {
    private Loggable logService;
    public Logger(Loggable logService) {
        if (logService == null) throw new ArgumentNullException ();
        this.logService = logService;
    }
    public void log (String text) {
        this.logService.Log(text);
    }
}


class Main () {
    public static void main(String[] args) {
        var ntfsLogger = new Logger(new NtfsFileSystem());
        var noSqlLogger = new Logger(new DbNoSql());
        ntfsLogger.log("some text");
        noSqlLogger.log("other text");
    }
}

Código

Buenas prácticas - DRY

Don't Repeat Yourself

Código

Buenas prácticas - Naming

int d;
int m;
int y;
int day;
int month;
int year;
static final String constante = "constante";
boolean change = false;
public class person {}
String getnombre();

static final String CONSTANTE = "VALOR CONSTANTE";
boolean isChange = false;
public class Person {}
public String getNombre();

public String getPersonData();
public String loadFamilyFilteredData();
public String requestRelativesData();
public String loadPersonData();
public String loadFamilyFilteredData();
public String loadRelativesData();

Código

Buenas prácticas - Funciones

Deben ser lo más pequeñas posible!

Deben hacer una cosa, hacerla bien y ser la única que la hace.

Menor cantidad de parámetros de entrada (<= 3)

Evitar side-effects

Código

Buenas prácticas - Comentarios

No siempre son malos

Pero trata de evitar el uso excesivo

Trata de que el código hable por si solo

NO MANTENER CÓDIGO COMENTADO o MUERTO!

Código

Buenas prácticas - Comentarios

/**
 *
 * @param title The title of the CD
 * @param author The author of the CD
 * @param tracks The number of tracks on the CD
 * @param durationInMinutes The duration of the CD in minutes
 */
 public void addCD(String title, String author, int tracks, int durationInMinutes) {
     CD cd = new CD();
     cd.title = title;
     cd.author = author;
     cd.tracks = tracks;
     cd.duration = duration;
     cdList.add(cd);
 }

Código

Buenas prácticas - Fomateo

if (condicion) {
    //...
}
if (condicion) 
{
    //...
}

Cual es mejor?

Código

Buenas prácticas - Fomateo

{name: 'prExists', width: 90, align: "center", sorttype: "string"},
                            {name: 'reason',width: 140,align: 'center', edittype: 'select', formatter: 'select',
                                editoptions:
            {
                    value: reasons,
                    defaultValue: '',
                    onchange: "selectOnChange(this)"
                },
                                editable: true,classes:'selectReason'},
            {name: 'sellable',width: 100,align: 'center', formatter: 'checkbox',editable: true,
                edittype: 'checkbox',
                                editoptions:
                                    {
                    value: 'Yes:No',
                    defaultValue: 'No',
                    onchange: "returnOnChange(this,'#008000')"
                },
                                classes:'selectSellable'},
                            {name: 'damaged',width: 100,align: 'center', formatter: 'checkbox',editable: true,
                edittype: 'checkbox',
                                editoptions:
                                    {
                    value: 'S:No',
                    defaultValue: 'No',
                    onchange: "returnOnChange(this,'#FFFF00')",
                }
                                ,classes:'selectDamaged'},
                            {name: 'bgBf',width: 90,align: 'center', formatter: 'checkbox',editable: true,
                edittype: 'checkbox',
                                editoptions:
                                    {
                    value: 'Y:No',
                    defaultValue: 'No',
                    onchange: "returnOnChange(this,'#FF0000')",

Código

Buenas prácticas - Fomateo

      {name: 'prExists', width: 90, align: "center", sorttype: "string"},
      {
        name: 'reason', width: 140, align: 'center', edittype: 'select', formatter: 'select',
        editoptions:
          {
            value: reasons,
            defaultValue: '',
            onchange: "selectOnChange(this)"
          },
        editable: true, classes: 'selectReason'
      },
      {
        name: 'sellable', width: 100, align: 'center', formatter: 'checkbox', editable: true,
        edittype: 'checkbox',
        editoptions:
          {
            value: 'Yes:No',
            defaultValue: 'No',
            onchange: "returnOnChange(this,'#008000')"
          },
        classes: 'selectSellable'
      },
      {
        name: 'damaged', width: 100, align: 'center', formatter: 'checkbox', editable: true,
        edittype: 'checkbox',
        editoptions:
          {
            value: 'S:No',
            defaultValue: 'No',
            onchange: "returnOnChange(this,'#FFFF00')",
          }
        , classes: 'selectDamaged'
      },
      {
        name: 'bgBf', width: 90, align: 'center', formatter: 'checkbox', editable: true,
        edittype: 'checkbox',
        editoptions:
          {
            value: 'Y:No',
            defaultValue: 'No',
            onchange: "returnOnChange(this,'#FF0000')",
          }
        , classes: 'selectBgBf'
      },

Código

Buenas prácticas - Fomateo/coding style

https://google.github.io/styleguide/javaguide.html

Linters

  • eslint
  • jshint
  • ...

http://errorprone.info/

http://checkstyle.sourceforge.net/

https://pmd.github.io/

Código

Buenas prácticas - Fomateo/coding style

http://docs.python-guide.org/en/latest/writing/style/
https://github.com/rubocop-hq/rubocop
https://www.gnu.org/prep/standards/html_node/Writing-C.html
https://github.com/linkedin/swift-style-guide

Código

Buenas prácticas - Tests

Tests independientes

1 test por escenario

Unit tests son el mínimo requerido

Código

Buenas prácticas - CSS

SMACSS

OOCSS

Suit CSS

Atomic

BEM

CSS Modules

Código

Buenas prácticas - CSS

https://www.webpagefx.com/blog/web-design/css-methodologies/
https://www.danylkoweb.com/Blog/5-methodologies-for-architecting-css-IP
https://github.com/css-modules/css-modules

Código

Buenas prácticas

Agile

Buenas prácticas - Definition of Done

Agile

Buenas prácticas - Stories

Descripción detallada y bien escrita

Incluir BDD escenario

Pair-programming

Deben ser discutidas por el equipo

Incluir criterio de aceptación

Agile

Buenas prácticas - CICD Pipeline

Agile

Buenas prácticas

Respetar las ceremonias

Ser HONESTOS en la Retrospective Meeting

Si tienes algún problema, pide ayuda

Deben ser discutidas por el equipo

PARTICIPA en las ceremonias!

Conclusion

Buenas prácticas

Mejor calidad del código

Mejor tiempo de entrega al mercado

Más tiempo para enfocarse en mejoras

Menor cantidad de bugs y menor tiempo en resolverlos

Mejor desarrollo personal y profesional

Conclusion

Buenas prácticas

Muchas Gracias!

Piero Divasto

Full-stack Developer

Nisum

Buenas prácticas en el desarrollo de software - Angular

By Piero Divasto

Buenas prácticas en el desarrollo de software - Angular

Presentación sobre buenas prácticas en el desarrollo de software. Esta esta dividida en tres secciones: Git, Código y Agile. La primera es un conjunto de buenas prácticas tales como nombrar features branches, resolver conflictos, etc. La siguiente es sobre buenas prácticas en el código basado en el gran libro "Clean Code". Para finalizar, se exponen buenas prácticas relacionadas con Agile, scrum y el equipo de desarrollo.

  • 772