api e invarianti
definisci contratti chiari: input validi, stati possibili, errori espliciti. meno superfici = meno bug. preferisci funzioni pure quando possibile e separa logica da I/O.
una buona api è facile da usare bene e difficile da usare male.
rule of zero/five
se una classe gestisce risorse (file, socket, memoria) definisci le cinque operazioni speciali. se puoi, usa tipi standard e resta nella rule of zero.
class Session {
public:
Session() = default;
Session(const Session&) = delete;
Session& operator=(const Session&) = delete;
Session(Session&&) = default;
Session& operator=(Session&&) = default;
};
pimpl e abi stabile
nascondi dettagli di implementazione per ridurre tempi di build e preservare compatibilità binaria.
class Renderer {
public:
Renderer();
~Renderer();
void draw();
private:
struct Impl;
std::unique_ptr<Impl> impl;
};
gestione errori
scegli uno stile coerente: eccezioni per errori eccezionali, std::optional o expected per flussi.
std::optional<Config> load_config(const std::string& path);
if (auto cfg = load_config("app.json")) {
// usa cfg
} else {
// fallback
}
interfacce e testabilità
- usa interfacce minime e dependency injection.
- separa layer: dominio, infrastruttura, presentation.
- crea fake e mock per test rapidi.
un'architettura pulita velocizza la manutenzione e il refactoring.
checklist finale
- api piccole con invarianti chiari.
- ownership esplicita e documentata.
- separazione dei layer con responsabilità singola.
- test automatici per ogni componente critico.
panoramica
In questo capitolo su architettura moderna, design pulito con ownership chiara, api stabili e codice testabile. L'obiettivo è trasformare i concetti in micro-pattern riutilizzabili con esempi piccoli e verificabili.
Lavora in sequenza: leggi, prova, modifica gli snippet e annota i trade-off principali (performance, leggibilità, manutenzione).
badge: architecture
obiettivi
- capire e applicare api e invarianti in uno scenario reale
- capire e applicare rule of zero/five in uno scenario reale
- capire e applicare pimpl e abi in uno scenario reale
- capire e applicare gestione errori in uno scenario reale
scheda rapida
#include <iostream>
#include <vector>
int main() {
std::vector<int> dati{1, 2, 3};
for (auto &v : dati) {
v *= 2;
}
for (const auto &v : dati) {
std::cout << v << " ";
}
std::cout << "\n";
return 0;
}
Adatta questo scheletro agli esempi della lezione e sostituisci i dati con il tuo dominio.
tips
- compila con warning elevati
- preferisci RAII
- usa const ovunque possibile
- separa moduli
- header minimal
- dipendenze unidirezionali
tip: Una buona architettura riduce i costi di compilazione.
mini progetto
Dividi un'app in moduli core/cli.
- definisci interfacce
- separa in cartelle
- crea build per modulo
- documenta dipendenze
output atteso: uno script o query ripetibile con risultati verificabili.