Princípios SOLID em C++: teoria e prática para código limpo

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course
Here is the translated HTML content in Portuguese, with all HTML tags preserved and only the text content translated. ```html

Princípios SOLID em C++: da teoria à prática



SOLID é um acrônimo de cinco princípios fundamentais da programação orientada a objetos, formulados por Robert Martin (Uncle Bob). No contexto de C++, esses princípios ajudam a criar código flexível, sustentável e testável. Neste artigo, vamos analisar cada princípio com exemplos práticos em C++.



1. Single Responsibility Principle (SRP) — Princípio da Responsabilidade Única



Essência: Cada classe deve ter apenas uma razão para mudar. Em palavras simples — a classe lida com apenas uma tarefa.



Exemplo ruim (violação do SRP):

class Report {public:    void generateReport() { /* geração do relatório */ }    void saveToFile(const std::string& filename) { /* salvar em arquivo */ }    void printReport() { /* imprimir relatório */ }};


Aqui, a classe Report é responsável por gerar, salvar e imprimir — três responsabilidades diferentes.



Exemplo bom (respeitando o SRP):

class Report {public:    std::string generate() { /* geração do relatório */ return "dados do relatório"; }};

class ReportSaver {public: void save(const std::string& data, const std::string& filename) { // salvar em arquivo }};

class ReportPrinter {public: void print(const std::string& data) { // imprimir relatório }};


Agora cada classe tem uma responsabilidade clara, o que simplifica os testes e a modificação.



2. Open-Closed Principle (OCP) — Princípio Aberto/Fechado



Essência: As classes devem estar abertas para extensão, mas fechadas para modificação. Você deve ser capaz de adicionar novas funcionalidades sem alterar o código existente.



Exemplo ruim:

enum class ShapeType { Circle, Rectangle };

class Shape {public: ShapeType type;};

class AreaCalculator {public: double calculateArea(const Shape& shape) { if (shape.type == ShapeType::Circle) { // cálculo da área do círculo return 3.14 * radius * radius; } else if (shape.type == ShapeType::Rectangle) { // cálculo da área do retângulo return width * height; } return 0.0; }};


Ao adicionar uma nova forma (por exemplo, triângulo), será necessário modificar AreaCalculator.



Exemplo bom (através de polimorfismo):

class Shape {public:    virtual double area() const = 0;    virtual ~Shape() = default;};

class Circle : public Shape { double radius;public: explicit Circle(double r) : radius(r) {} double area() const override { return 3.14159 * radius * radius; }};

class Rectangle : public Shape { double width, height;public: Rectangle(double w, double h) : width(w), height(h) {} double area() const override { return width * height; }};

class AreaCalculator {public: double calculateArea(const Shape& shape) { return shape.area(); }};


Agora, para adicionar uma nova forma, basta criar uma nova classe derivada, sem tocar em AreaCalculator.



3. Liskov Substitution Principle (LSP) — Princípio da Substituição de Barbara Liskov



Essência: Objetos de subclasses devem ser intercambiáveis com objetos da classe base sem quebrar a correção do programa.



Violacão clássica (retângulo-quadrado):

class Rectangle {protected:    int width, height;public:    void setWidth(int w) { width = w; }    void setHeight(int h) { height = h; }    int area() const { return width * height; }};

class Square : public Rectangle {public: void setWidth(int w) override { width = w; height ```

Blogs

Book Recommendations