PV

Conceitos de SOLID

ons-2026 • 15/05/2026

Principios de SOLID aplicados ao projeto Batcaverna-PV

Construir o BatCaverna Editor é uma tarefa de alta responsabilidade. Se o Batman vai usar esse software para registrar investigações ou analisar dados da Wayne Enterprises, o código precisa ser tão robusto e à prova de falhas quanto o próprio cinto de utilidades.

Aplicar os princípios SOLID vai garantir que o seu editor seja fácil de manter, testar e expandir. Vamos traduzir esses cinco princípios para o contexto do seu projeto (usando TypeScript/C# como base conceitual).


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

O Conceito: Uma classe deve ter apenas um motivo para mudar. No BatCaverna Editor: Não misture a lógica de interface do usuário, manipulação de texto e salvamento de arquivos na mesma classe.

❌ O Jeito Errado (Classe Faz-Tudo):

class BatDocument {
    public text: string;
    
    public formatText() { /* Negrito, itálico... */ }
    public saveToBatComputer() { /* Lógica de acesso ao disco... */ }
    public printToBatPrinter() { /* Lógica de impressão... */ }
}

✅ O Jeito SOLID: Divida as responsabilidades. Se a rede do Batcomputador mudar, você só altera a classe de salvamento, sem o risco de quebrar a formatação de texto.

class BatDocument {
    public text: string;
}

class DocumentFormatter {
    public format(doc: BatDocument) { /* ... */ }
}

class DocumentStorage {
    public save(doc: BatDocument) { /* ... */ }
}

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

O Conceito: O código deve estar aberto para extensão, mas fechado para modificação. No BatCaverna Editor: Se você quiser adicionar um novo formato de exportação (ex: exportar para PDF, ou para um formato criptografado da WayneCorp), você não deve precisar alterar a classe principal que gerencia as exportações.

✅ O Jeito SOLID: Use interfaces ou classes abstratas.

interface IFileExporter {
    export(text: string): void;
}

class PdfExporter implements IFileExporter {
    export(text: string) { console.log("Exportando PDF..."); }
}

class WayneCorpEncryptedExporter implements IFileExporter {
    export(text: string) { console.log("Criptografando nível militar..."); }
}

// A classe abaixo nunca precisará ser modificada quando um novo formato surgir!
class ExportManager {
    public exportDocument(text: string, exporter: IFileExporter) {
        exporter.export(text);
    }
}

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

O Conceito: Classes derivadas devem poder substituir suas classes base sem quebrar o sistema. No BatCaverna Editor: Se você tem um documento “Somente Leitura” (ex: um dossiê finalizado do Coringa), ele não deve herdar de uma classe que o force a ter um método de edição que lance um erro.

❌ O Jeito Errado:

class Document {
    public write(text: string): void { /* ... */ }
}

class ReadOnlyDossier extends Document {
    public write(text: string): void {
        throw new Error("Não é possível editar um dossiê finalizado!"); // Quebra o princípio!
    }
}

✅ O Jeito SOLID: Crie abstrações que façam sentido.

interface IReadableDocument {
    read(): string;
}

interface IWritableDocument extends IReadableDocument {
    write(text: string): void;
}

class DraftDocument implements IWritableDocument { /* Lê e Escreve */ }
class ReadOnlyDossier implements IReadableDocument { /* Apenas Lê */ }

4. ISP - Princípio da Segregação de Interfaces (Interface Segregation Principle)

O Conceito: Nenhuma classe deve ser forçada a depender de métodos que não usa. No BatCaverna Editor: Imagine que você quer criar um sistema de plugins para o editor. Não crie uma interface gigante que obrigue todo plugin a ter botões na UI e atalhos de teclado se alguns plugins rodam apenas em background.

✅ O Jeito SOLID: Quebre as interfaces em partes menores e mais específicas.

interface IBackgroundPlugin {
    executeInBackground(): void;
}

interface IUIPlugin {
    renderToolbarButton(): void;
}

// Um plugin de Auto-Save só precisa da interface de background
class AutoSavePlugin implements IBackgroundPlugin {
    executeInBackground() { /* Salva a cada 5 minutos */ }
}

5. DIP - Princípio da Inversão de Dependência (Dependency Inversion Principle)

O Conceito: Dependa de abstrações, não de implementações concretas. Módulos de alto nível não devem depender de módulos de baixo nível. No BatCaverna Editor: A interface principal do editor não deve instanciar diretamente o banco de dados ou a API da nuvem. Ela deve receber a dependência “injetada”.

✅ O Jeito SOLID:

interface IDatabase {
    saveLog(log: string): void;
}

class OracleCloudDatabase implements IDatabase {
    saveLog(log: string) { /* Envia para os servidores da Oráculo */ }
}

class EditorCore {
    private db: IDatabase;

    // A dependência é injetada via construtor. O Core não sabe QUAL banco está usando, 
    // apenas sabe que ele obedece à interface IDatabase.
    constructor(database: IDatabase) {
        this.db = database;
    }

    public performAction() {
        this.db.saveLog("Ação realizada pelo Batman.");
    }
}

Aplicando essas regras, o núcleo do seu editor ficará imune a “efeitos colaterais” quando você precisar adicionar novas funcionalidades ou trocar tecnologias no futuro.