Princípios SOLID em C++: teoria e prática com exemplos de código

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
Aqui está a tradução do conteúdo HTML educacional do russo para o português (Português), mantendo todas as tags HTML e os termos técnicos em inglês:

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



Os princípios SOLID são cinco regras fundamentais de design orientado a objetos, formuladas por Robert Martin. Eles ajudam a criar código flexível, escalável e de fácil manutenção. Neste artigo, vamos analisar cada princípio com exemplos em C++, desde a teoria simples até casos práticos reais.



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



Teoria: Cada classe deve ter apenas um motivo para ser alterada. Em outras palavras, a classe é responsável por apenas uma parte da funcionalidade do programa.



Problema: Frequentemente, os desenvolvedores colocam em uma única classe a lógica de manipulação de dados, seu salvamento e exibição na tela. Isso viola o SRP.



Prática em C++: Vamos dividir a classe Report em três classes separadas.



// Ruim: viola o SRPclass Report {    std::string title;    std::string content;public:    void generate() { /* geração do relatório */ }    void saveToFile(const std::string& filename) { /* salvamento em arquivo */ }    void print() { /* impressão */ }};

// Bom: respeita o SRPclass Report { std::string title; std::string content;public: void generate() { /* apenas geração */ }};

class ReportSaver {public: void saveToFile(const Report& report, const std::string& filename) { /* salvamento */ }};

class ReportPrinter {public: void print(const Report& report) { /* impressão */ }};


Conclusão: Agora cada classe é responsável pela sua própria tarefa. O código se tornou mais fácil de testar e modificar.



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



Teoria: Entidades de software (classes, módulos, funções) devem estar abertas para extensão, mas fechadas para modificação. Ou seja, devemos ser capazes de adicionar novas funcionalidades sem alterar o código existente.



Prática em C++: Usamos polimorfismo e classes abstratas.



#include <iostream>#include <vector>#include <memory>

// Classe base para formasclass Shape {public: virtual double area() const = 0; virtual ~Shape() = default;};

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 Circle : public Shape { double radius;public: Circle(double r) : radius(r) {} double area() const override { return 3.14159 * radius * radius; }};

// Classe para calcular a área total — não requer alterações ao adicionar novas formasclass AreaCalculator {public: double totalArea(const std::vector<std::unique_ptr<Shape>>& shapes) { double total = 0; for (const auto& shape : shapes) { total += shape->area(); } return total; }};

int main() { std::vector<std::unique_ptr<Shape>> shapes; shapes.push_back(std::make_unique<Rectangle>(4, 5)); shapes.push_back(std::make_unique<Circle>(3));

AreaCalculator calc; std::cout << "Total area: " << calc.totalArea(shapes) << std::endl; return 0;}


Conclusão: Podemos adicionar novas formas (por exemplo, Triangle) sem modificar o AreaCalculator.



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



Teoria: Os objetos em um programa devem ser substituíveis por instâncias de seus subtipos sem quebrar a correção do programa. Simplificando, se você tem uma classe pai e uma classe filha, você deve ser capaz de usar a filha onde a pai é esperada, e tudo deve funcionar.



Prática

Blogs

Book Recommendations