Extreme programming (XP) și Regulile lui Fred George

 Extreme programming (XP)

Extreme Programming (XP) este o metodă de dezvoltare software agilă care promovează practici și principii menite să îmbunătățească calitatea și flexibilitatea procesului de dezvoltare. XP a fost dezvoltată la începutul anilor 2000 de către Kent Beck și a devenit una dintre primele metodologii agile semnificative. Aceasta se bazează pe ideea că cerințele și soluțiile în dezvoltarea software sunt adesea dificil de anticipat în stadiile incipiente ale unui proiect, astfel încât metodele agile răspund la schimbare prin colaborare și adaptabilitate.

Iată câteva principii și practici-cheie asociate cu Extreme Programming (XP):

  • Comunicare constantă:

    • Echipele XP favorizează o comunicare constantă între toți membrii echipei și între dezvoltatori și clienți. Comunicarea deschisă și transparentă este esențială pentru înțelegerea clară a cerințelor și schimbarea eficientă a direcției proiectului.
  • Testare automată:

    • XP pune un accent deosebit pe testarea automată a codului. Dezvoltatorii scriu teste automate înainte de a scrie codul efectiv, asigurându-se că orice modificare nu afectează funcționalitatea existentă și oferă o bază solidă pentru refactorizare.
  • Dezvoltare iterativă și incrementală:

    • Proiectul este dezvoltat în iterații scurte, de obicei de 1-3 săptămâni. La sfârșitul fiecărei iterații, software-ul este gata pentru a fi livrat. Această abordare permite echipei să obțină feedback rapid și să se adapteze în consecință.
  • Programare în pereche (Pair Programming):

    • În XP, este obișnuită practicarea programării în pereche, unde doi SW developeri lucrează la același cod și se ajută reciproc. Aceasta îmbunătățește calitatea codului, reduce bug-urile și facilitează transferul de cunoștințe între membrii echipei.
  • Refactorizare continuă:

    • XP încurajează refactorizarea continuă a codului pentru a menține acesta simplu și ușor de înțeles. Dezvoltatorii sunt încurajați să îmbunătățească constant design-ul software-ului pe măsură ce proiectul evoluează.
  • Standarde de cod:

    • Utilizarea unor standarde de cod clar definite facilitează înțelegerea și mentenanța codului. Aceasta contribuie la consistență în întreaga aplicație și face echipele mai eficiente.
  • Design simplu:

    • XP promovează un design simplu și elegant, evitând complexitatea excesivă. Principiul KISS (Keep It Simple, Stupid) este adesea urmat pentru a menține codul cât mai simplu și clar posibil.

Extreme Programming este adaptabilă și poate fi ajustată pentru a se potrivi diferitelor contexte de dezvoltare software. Principiile și practicile XP sunt concepute pentru a oferi rapiditate, flexibilitate și calitate în procesul de dezvoltare a software-ului.

Regulile lui Fred George

Fred George este un software developer cu experiență, care a fost implicat în domeniul programării și al tehnologiei pentru o perioadă semnificativă. El este cunoscut în special pentru contribuțiile sale în domeniul programării agile și a extreme programming (XP). 



Regulile lui Fred George sunt aliniate cu principile de "clean code", design simplificat și programarea orientată pe obiect, dar a preluat mare parte din aceste reguli din extreme programming (XP).


1. Fără Instrucțiuni if:
   - Regula: Evită utilizarea instrucțiunilor if în codul tău.
   - Exemplu:

// În loc de o instrucțiune if, poți utiliza polimorfism sau 
// alte tehnici pentru a obține același rezultat fără condiții explicite.

// Exemplu:
class Car {
public:
    virtual void start() const = 0;
};

class ElectricCar : public Car {
public:
    void start() const override {
        // Logica specifică pentru pornirea unui automobil electric
    }
};

class GasolineCar : public Car {
public:
    void start() const override {
        // Logica specifică pentru pornirea unui automobil cu benzină
    }
};

// Utilizare:
Car* myCar = new ElectricCar();  // sau GasolineCar, în funcție de condiție
myCar->start();

2. Fără instrucțiuni else :
   - Regula: Similar cu prima regulă, evită utilizarea instrucțiunilor else.
   - Exemplu

// Folosește return-uri timpurii sau polimorfism pentru 
// a gestiona diferite cazuri fără a folosi ramuri `else`.

#include <iostream>

// Folosește return-uri timpurii pentru a evita instrucțiunile `else`
bool isPositive(int number) {
    if (number > 0) {
        return true;
    }
    return false;
}

// Sau într-o formă mai simplificată
bool isNegative(int number) {
    return (number < 0);
}

int main() {
    int testNumber = 5;

    // Exemplu de utilizare pentru isPositive
    if (isPositive(testNumber)) {
        std::cout << ``Numarul este pozitiv.`` << std::endl;
    } else {
        std::cout << ``Numarul nu este pozitiv.`` << std::endl;
    }

    // Exemplu de utilizare pentru isNegative
    if (isNegative(testNumber)) {
        std::cout << ``Numarul este negativ.`` << std::endl;
    } else {
        std::cout << ``Numarul nu este negativ.`` << std::endl;
    }

    return 0;
}


3. Fără cuvinte-cheie pentru bucle (for , while , etc.):
   - Regula: Evită utilizarea buclelor tradiționale; în schimb, folosește funcții de ordin superior.
   - Exemplu:

// Folosește construcții de programare funcțională precum 
// `for_each`, `map`, `filter`, și `reduce` în loc de bucle `for` sau `while`.

// Exemplu:
#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> numbers = {1, 2, 3, 4, 5};

    // Folosind std::for_each în loc de buclă for
    std::for_each(numbers.begin(), numbers.end(), [](int num) {
        std::cout << num << " ";
    });

    // Folosind std::transform în loc de buclă for pentru a crea un nou container
    std::vector<int> squaredNumbers;
    std::transform(numbers.begin(), numbers.end(), std::back_inserter(squaredNumbers),
                   [](int num) { return num * num; });

    // Folosind std::accumulate în loc de buclă for pentru a calcula suma
    int sum = std::accumulate(numbers.begin(), numbers.end(), 0);

    return 0;
}

4. Fără Instrucțiuni switch :
   - Regula: Evită utilizarea instrucțiunilor switch.
   - Exemplu:

// Folosește polimorfism sau alte tehnici pentru a gestiona mai multe cazuri 
// fără a utiliza o instrucțiune `switch`.

// Exemplu:
class Shape {
public:
    virtual void draw() const = 0;
};

class Circle : public Shape {
public:
    void draw() const override {
        // Logica de desenare pentru un cerc
    }
};

class Square : public Shape {
public:
    void draw() const override {
        // Logica de desenare pentru un pătrat
    }
};

// Utilizare:
Shape* shape = new Circle();  // sau Square, în funcție de condiție
shape->draw();

5. Fără folosirea metodelor Getters/Setters/Proprietăți:
   - Regula: Evită expunerea proprietăților unui obiect direct prin intermediul getterelor și setterelor.
   - Exemplu:

// Încapsulează comportamentul în cadrul obiectului și 
// furnizează metode care reprezintă acțiuni în loc să expui starea internă.

// Exemplu:
class Car {
private:
    bool engineRunning;

public:
    void startEngine() {
        // Logica de pornire a motorului
        engineRunning = true;
    }

    void stopEngine() {
        // Logica de oprire a motorului
        engineRunning = false;
    }
};

6. Fără acronime de 3 litere:
   - Regula: Evită utilizarea de nume de variabile sau metode neclare și ambigue.
   - Exemplu:

// În loc să folosești un acronim scurt și neclar, utilizează nume descriptive
// care transmit scopul variabilei sau metodei.

// Exemplu:
class DatabaseConnection {
public:
    void establishConnection() {
        // Logica de stabilire a conexiunii cu baza de date
    }
};

7. Funcțiile ar trebui să fie mici :
   - Regula: Menține funcțiile mici, complexitatea mică și concentrate pe o singură responsabilitate.
   - Exemplu:

// Descompune funcții complexe în funcții mai mici și mai ușor de gestionat,
// fiecare responsabilă pentru o sarcină specifică.

// Exemplu:
void processOrder(Order order) {
    validateOrder(order);
    calculateTotal(order);
    applyDiscount(order);
    generateInvoice(order);
}

void validateOrder(Order order) {
    // Logica de validare a comenzii
}

void calculateTotal(Order order) {
    // Logica de calcul al totalului comenzii
}

void applyDiscount(Order order) {
    // Logica de aplicare a discountului
}

void generateInvoice(Order order) {
    // Logica de generare a facturii
}

8. Nici o clasă mai mare de 50 de linii:
   - Regula: Menține clasele scurte și concentrate, care ar trebui să încapă pe o foaie A4. Ar putea să se aplice și în C pentru un modul.
   - Exemplu:

// Descompune clasele mari în clase mai mici,
// fiecare responsabilă pentru o parte specifică a funcționalității.

// Exemplu:
class Customer {
private:
    // Atribute

public:
    // Metode

private:
    // Alte metode
};

Aceste reguli reflectă stilul personal al lui Fred George și preferințele sale. Este important să reții că aplicabilitatea lor poate depinde de contextul specific și cerințele proiectului. 

Opinia mea

Cred că regulile 1, 3, 4 nu prea sunt aplicabile, pentru că la final ajungi să muți deciziile și procesările de la nivelul clasei la nivelul main, care până la urmă tot pe if, for, while si switch se bazează. De exemplu se mută condiția if-ului din clasa X în main, și practic nu s-a rezolvat nimic. 

Celelalte reguli eu consider că sunt foarte bune și ar trebui folosite chiar și în C.  Prin folosirea acestor reguli se vor simplifica funcțiile, iar codul o să fie mult mai ușor de citit, schimbat și de întreținut, deci se pot face corecții foarte repede și eficient.

Mulțumesc pentru atenție!

Pentru întrebări și/sau consultanță tehnică vă stau la dispoziție pe blog mai jos în secțiunea de comentarii sau pe email simedruflorin@automatic-house.ro.
O zi plăcută tuturor !
Back to top of page

Etichete

Afișați mai multe

Arhiva

Afișați mai multe