Skip to content

Instantly share code, notes, and snippets.

@jefBinomed
Created June 11, 2025 10:12
Show Gist options
  • Save jefBinomed/f5445c3276e4b46c79095c7fcac93594 to your computer and use it in GitHub Desktop.
Save jefBinomed/f5445c3276e4b46c79095c7fcac93594 to your computer and use it in GitHub Desktop.
Ada School - Exemple de schéma POO sur un cas de Banque en typscript (fait en séance) et un cas java (généré par IA)
/**
* Interface définissant le contrat pour toutes les opérations bancaires
* Principe : Tout objet transactionnable doit pouvoir effectuer ces opérations
*/
public interface Transactionnable {
boolean deposer(double montant);
boolean retirer(double montant);
double consulterSolde();
}
/**
* Classe abstraite représentant un compte bancaire générique
* Contient les attributs et méthodes communes à tous les types de comptes
*/
public abstract class Compte implements Transactionnable {
protected String numeroCompte;
protected double solde;
protected Client proprietaire;
protected java.util.List<Transaction> historique;
// Constructeur
public Compte(String numeroCompte, Client proprietaire) {
this.numeroCompte = numeroCompte;
this.proprietaire = proprietaire;
this.solde = 0.0;
this.historique = new java.util.ArrayList<>();
}
// Méthode commune à tous les comptes
@Override
public double consulterSolde() {
return this.solde;
}
// Méthode commune pour le dépôt
@Override
public boolean deposer(double montant) {
if (montant > 0) {
this.solde += montant;
ajouterTransaction("DEPOT", montant);
return true;
}
return false;
}
// Méthode abstraite - chaque type de compte aura sa propre logique de retrait
@Override
public abstract boolean retirer(double montant);
// Méthode abstraite pour calculer les intérêts (spécifique à chaque type)
public abstract double calculerInterets();
// Méthode utilitaire pour ajouter une transaction
protected void ajouterTransaction(String type, double montant) {
Transaction transaction = new Transaction(type, montant, this.solde);
this.historique.add(transaction);
}
// Getters
public String getNumeroCompte() { return numeroCompte; }
public Client getProprietaire() { return proprietaire; }
public java.util.List<Transaction> getHistorique() { return historique; }
}
/**
* Compte courant avec découvert autorisé
*/
public class CompteCourant extends Compte {
private double decouvertAutorise;
public CompteCourant(String numeroCompte, Client proprietaire, double decouvertAutorise) {
super(numeroCompte, proprietaire);
this.decouvertAutorise = decouvertAutorise;
}
@Override
public boolean retirer(double montant) {
// Permet le retrait même en découvert (dans la limite autorisée)
if (montant > 0 && (this.solde - montant) >= -this.decouvertAutorise) {
this.solde -= montant;
ajouterTransaction("RETRAIT", montant);
return true;
}
return false;
}
@Override
public double calculerInterets() {
// Pas d'intérêts sur un compte courant, mais des frais si découvert
return this.solde < 0 ? this.solde * 0.05 : 0; // 5% de frais sur le découvert
}
public double getDecouvertAutorise() { return decouvertAutorise; }
}
/**
* Compte épargne avec intérêts mais pas de découvert
*/
public class CompteEpargne extends Compte {
private double tauxInteret;
public CompteEpargne(String numeroCompte, Client proprietaire, double tauxInteret) {
super(numeroCompte, proprietaire);
this.tauxInteret = tauxInteret;
}
@Override
public boolean retirer(double montant) {
// Pas de découvert autorisé sur un compte épargne
if (montant > 0 && montant <= this.solde) {
this.solde -= montant;
ajouterTransaction("RETRAIT", montant);
return true;
}
return false;
}
@Override
public double calculerInterets() {
// Calcul des intérêts sur le solde positif
return this.solde * this.tauxInteret / 100;
}
public double getTauxInteret() { return tauxInteret; }
}
/**
* Compte professionnel avec découvert important et frais de gestion
*/
public class CompteProfessionnel extends Compte {
private double decouvertAutorise;
private double fraisGestion;
public CompteProfessionnel(String numeroCompte, Client proprietaire, double decouvertAutorise) {
super(numeroCompte, proprietaire);
this.decouvertAutorise = decouvertAutorise;
this.fraisGestion = 10.0; // Frais fixes mensuels
}
@Override
public boolean retirer(double montant) {
// Découvert important autorisé pour les professionnels
if (montant > 0 && (this.solde - montant) >= -this.decouvertAutorise) {
this.solde -= montant;
ajouterTransaction("RETRAIT", montant);
return true;
}
return false;
}
@Override
public double calculerInterets() {
// Frais de gestion fixes + frais sur découvert
double frais = -this.fraisGestion;
if (this.solde < 0) {
frais += this.solde * 0.03; // 3% sur le découvert
}
return frais;
}
public double getDecouvertAutorise() { return decouvertAutorise; }
public double getFraisGestion() { return fraisGestion; }
}
/**
* Classe mère représentant un client de la banque
*/
public class Client {
protected String id;
protected String nom;
protected String email;
protected java.util.List<Compte> comptes;
public Client(String id, String nom, String email) {
this.id = id;
this.nom = nom;
this.email = email;
this.comptes = new java.util.ArrayList<>();
}
public void ajouterCompte(Compte compte) {
this.comptes.add(compte);
}
// Méthode virtuelle qui peut être redéfinie dans les classes filles
public String getTypeClient() {
return "Client générique";
}
// Getters
public String getId() { return id; }
public String getNom() { return nom; }
public String getEmail() { return email; }
public java.util.List<Compte> getComptes() { return comptes; }
}
/**
* Client particulier avec des spécificités propres aux individus
*/
public class ClientParticulier extends Client {
private String dateNaissance;
public ClientParticulier(String id, String nom, String email, String dateNaissance) {
super(id, nom, email);
this.dateNaissance = dateNaissance;
}
@Override
public String getTypeClient() {
return "Particulier";
}
// Méthode spécifique aux particuliers
public boolean peutOuvrirCompteEpargne() {
return true; // Les particuliers peuvent toujours ouvrir un compte épargne
}
public String getDateNaissance() { return dateNaissance; }
}
/**
* Client entreprise avec des spécificités propres aux sociétés
*/
public class ClientEntreprise extends Client {
private String siret;
private String secteurActivite;
public ClientEntreprise(String id, String nom, String email, String siret, String secteurActivite) {
super(id, nom, email);
this.siret = siret;
this.secteurActivite = secteurActivite;
}
@Override
public String getTypeClient() {
return "Entreprise";
}
// Méthode spécifique aux entreprises
public double getLimiteDecouvertAutorisee() {
// Les entreprises ont des limites de découvert plus importantes
return 50000.0;
}
public String getSiret() { return siret; }
public String getSecteurActivite() { return secteurActivite; }
}
/**
* Classe représentant une transaction bancaire
*/
public class Transaction {
private String type;
private double montant;
private double soldeApres;
private java.time.LocalDateTime dateHeure;
public Transaction(String type, double montant, double soldeApres) {
this.type = type;
this.montant = montant;
this.soldeApres = soldeApres;
this.dateHeure = java.time.LocalDateTime.now();
}
@Override
public String toString() {
return String.format("%s - %s: %.2f€ (Solde: %.2f€)",
dateHeure.format(java.time.format.DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm")),
type, montant, soldeApres);
}
// Getters
public String getType() { return type; }
public double getMontant() { return montant; }
public double getSoldeApres() { return soldeApres; }
public java.time.LocalDateTime getDateHeure() { return dateHeure; }
}
/**
* Classe gérant l'ensemble du système bancaire
*/
public class Banque {
private String nom;
private java.util.List<Client> clients;
private java.util.List<Compte> comptes;
private int prochainNumeroCompte;
public Banque(String nom) {
this.nom = nom;
this.clients = new java.util.ArrayList<>();
this.comptes = new java.util.ArrayList<>();
this.prochainNumeroCompte = 1000;
}
// Ajouter un client
public void ajouterClient(Client client) {
this.clients.add(client);
System.out.println("Client " + client.getNom() + " ajouté à la banque " + this.nom);
}
// Créer un compte pour un client
public Compte creerCompte(String typeCompte, Client client) {
String numeroCompte = "CPT" + (prochainNumeroCompte++);
Compte compte = null;
switch (typeCompte.toUpperCase()) {
case "COURANT":
double decouvert = (client instanceof ClientEntreprise) ? 10000.0 : 1000.0;
compte = new CompteCourant(numeroCompte, client, decouvert);
break;
case "EPARGNE":
compte = new CompteEpargne(numeroCompte, client, 2.5); // 2.5% d'intérêt
break;
case "PROFESSIONNEL":
if (client instanceof ClientEntreprise) {
compte = new CompteProfessionnel(numeroCompte, client,
((ClientEntreprise) client).getLimiteDecouvertAutorisee());
}
break;
}
if (compte != null) {
this.comptes.add(compte);
client.ajouterCompte(compte);
System.out.println("Compte " + typeCompte + " créé: " + numeroCompte);
}
return compte;
}
// Afficher le résumé de tous les comptes
public void afficherResume() {
System.out.println("\n=== RÉSUMÉ BANQUE " + this.nom + " ===");
System.out.println("Nombre de clients: " + this.clients.size());
System.out.println("Nombre de comptes: " + this.comptes.size());
for (Compte compte : this.comptes) {
System.out.printf("Compte %s (%s) - Propriétaire: %s - Solde: %.2f€%n",
compte.getNumeroCompte(),
compte.getClass().getSimpleName(),
compte.getProprietaire().getNom(),
compte.consulterSolde());
}
}
// Getters
public String getNom() { return nom; }
public java.util.List<Client> getClients() { return clients; }
public java.util.List<Compte> getComptes() { return comptes; }
}
/**
* Classe principale démontrant l'utilisation du système bancaire
*/
public class Main {
public static void main(String[] args) {
System.out.println("=== SYSTÈME BANCAIRE - DÉMONSTRATION ===\n");
// 1. Création de la banque
Banque banque = new Banque("Banque Populaire du Code");
// 2. Création des clients
ClientParticulier alice = new ClientParticulier("P001", "Alice Martin", "[email protected]", "15/03/1985");
ClientEntreprise techCorp = new ClientEntreprise("E001", "TechCorp SARL", "[email protected]", "12345678901234", "Informatique");
banque.ajouterClient(alice);
banque.ajouterClient(techCorp);
// 3. Création des comptes
System.out.println("\n--- Création des comptes ---");
Compte compteAliceCourant = banque.creerCompte("COURANT", alice);
Compte compteAliceEpargne = banque.creerCompte("EPARGNE", alice);
Compte compteTechCorpPro = banque.creerCompte("PROFESSIONNEL", techCorp);
// 4. Démonstration des opérations bancaires
System.out.println("\n--- Opérations bancaires ---");
// Opérations sur le compte courant d'Alice
System.out.println("Alice dépose 1000€ sur son compte courant:");
compteAliceCourant.deposer(1000);
System.out.println("Solde: " + compteAliceCourant.consulterSolde() + "€");
System.out.println("\nAlice retire 1200€ (test découvert):");
boolean retraitReussi = compteAliceCourant.retirer(1200);
System.out.println("Retrait réussi: " + retraitReussi);
System.out.println("Solde après retrait: " + compteAliceCourant.consulterSolde() + "€");
// Opérations sur le compte épargne d'Alice
System.out.println("\n--- Compte Épargne d'Alice ---");
compteAliceEpargne.deposer(5000);
System.out.println("Dépôt de 5000€ sur le compte épargne");
System.out.println("Solde épargne: " + compteAliceEpargne.consulterSolde() + "€");
System.out.println("\nTentative de retrait de 6000€ (plus que le solde):");
boolean retraitEpargne = compteAliceEpargne.retirer(6000);
System.out.println("Retrait réussi: " + retraitEpargne);
System.out.println("Solde épargne: " + compteAliceEpargne.consulterSolde() + "€");
// Opérations sur le compte professionnel de TechCorp
System.out.println("\n--- Compte Professionnel TechCorp ---");
compteTechCorpPro.deposer(25000);
System.out.println("Dépôt de 25000€ sur le compte professionnel");
compteTechCorpPro.retirer(35000);
System.out.println("Retrait de 35000€ (utilisation du découvert professionnel)");
System.out.println("Solde professionnel: " + compteTechCorpPro.consulterSolde() + "€");
// 5. Démonstration du polymorphisme
System.out.println("\n--- Démonstration du polymorphisme ---");
java.util.List<Compte> tousLesComptes = java.util.Arrays.asList(
compteAliceCourant, compteAliceEpargne, compteTechCorpPro
);
System.out.println("Calcul des intérêts/frais pour tous les comptes:");
for (Compte compte : tousLesComptes) {
double interets = compte.calculerInterets();
System.out.printf("Compte %s (%s): %.2f€%n",
compte.getNumeroCompte(),
compte.getClass().getSimpleName(),
interets);
}
// 6. Affichage des historiques de transactions
System.out.println("\n--- Historique des transactions ---");
System.out.println("Historique du compte courant d'Alice:");
for (Transaction transaction : compteAliceCourant.getHistorique()) {
System.out.println(" " + transaction);
}
System.out.println("\nHistorique du compte épargne d'Alice:");
for (Transaction transaction : compteAliceEpargne.getHistorique()) {
System.out.println(" " + transaction);
}
// 7. Démonstration de l'héritage avec les types de clients
System.out.println("\n--- Types de clients ---");
for (Client client : banque.getClients()) {
System.out.println("Client: " + client.getNom() + " - Type: " + client.getTypeClient());
if (client instanceof ClientParticulier) {
ClientParticulier particulier = (ClientParticulier) client;
System.out.println(" Peut ouvrir compte épargne: " + particulier.peutOuvrirCompteEpargne());
}
if (client instanceof ClientEntreprise) {
ClientEntreprise entreprise = (ClientEntreprise) client;
System.out.println(" Limite découvert autorisée: " + entreprise.getLimiteDecouvertAutorisee() + "€");
System.out.println(" Secteur: " + entreprise.getSecteurActivite());
}
}
// 8. Résumé final de la banque
banque.afficherResume();
// 9. Démonstration de l'interface Transactionnable
System.out.println("\n--- Démonstration interface Transactionnable ---");
demonstrerInterface(compteAliceCourant);
demonstrerInterface(compteAliceEpargne);
}
/**
* Méthode démontrant l'utilisation de l'interface Transactionnable
* Accepte n'importe quel objet implémentant cette interface
*/
private static void demonstrerInterface(Transactionnable compte) {
System.out.println("Opérations via l'interface Transactionnable:");
System.out.println(" Solde actuel: " + compte.consulterSolde() + "€");
// Test de dépôt via l'interface
boolean depotReussi = compte.deposer(100);
System.out.println(" Dépôt de 100€: " + (depotReussi ? "Réussi" : "Échec"));
System.out.println(" Nouveau solde: " + compte.consulterSolde() + "€");
System.out.println();
}
}
enum TYPE_COMPTE{
COURRANT, EPARGNE, PRO
}
interface ITransactionnable{
debit(montant: number): boolean;
credit(montant : number) : boolean;
consulterSolde() : number;
}
abstract class Compte implements ITransactionnable{
numeroDeCompte: string;
solde: number = 0;
transactionList: Transaction[] = [];
proprietaire: Client;
constructor(numeroDeCompte: string, proprietaire: Client){
this.numeroDeCompte = numeroDeCompte;
this.proprietaire = proprietaire;
}
abstract getTypeCompte(): TYPE_COMPTE;
ajoutTransaction(typeTransaction : TYPE_TRANSACTION, montant : number){
if (typeTransaction === TYPE_TRANSACTION.DEBIT){
this.transactionList.push(new Debit(montant, this.solde));
}else{
this.transactionList.push(new Credit(montant, this.solde));
}
}
/**
* Ne devrait pas être demandé ici
*/
abstract debit(montant: number): boolean;
/**
* Surcharge volontaire de méthodes de mon interface
*/
credit(montant : number) : boolean{
if (montant > 0){
this.solde += montant;
this.ajoutTransaction(TYPE_TRANSACTION.CREDIT, montant);
return true;
}
return false;
};
consulterSolde() : number{
return this.solde;
}
consulterHistorique(): Transaction[]{
return this.transactionList;
}
abstract getInterets(): number;
}
class CompteCourrant extends Compte{
getTypeCompte(){
return TYPE_COMPTE.COURRANT;
}
debit(montant: number){
this.solde -= montant;
super.ajoutTransaction(TYPE_TRANSACTION.DEBIT, montant);
return true;
}
getInterets(){
return 0;
}
}
class ComptePro extends CompteCourrant{
getTypeCompte(){
return TYPE_COMPTE.PRO;
}
}
class CompteEpargne extends Compte{
getTypeCompte(){
return TYPE_COMPTE.EPARGNE;
}
debit(montant: number){
if (this.solde - montant > 0){
this.solde -= montant;
super.ajoutTransaction(TYPE_TRANSACTION.DEBIT, montant);
return true;
}
return false;
}
getInterets(){
return this.solde * 0.05;
}
}
enum TYPE_CLIENT{
PRO, PARTICULIER
}
abstract class Client{
nom: string;
numero: string;
compteList: Compte[] = [];
constructor(nom: string, numero: string){
this.nom = nom;
this.numero = numero;
}
ajouterCompte(compte: Compte){
this.compteList.push(compte);
}
retirerCompte(compte: Compte){
this.compteList = this.compteList.filter((compteTemp)=> compte.numeroDeCompte !== compteTemp.numeroDeCompte);
}
abstract getTypeClient(): TYPE_CLIENT;
}
class Particulier extends Client{
getTypeClient(){
return TYPE_CLIENT.PARTICULIER;
}
}
class Pro extends Client{
getTypeClient(){
return TYPE_CLIENT.PRO;
}
}
enum TYPE_TRANSACTION {
DEBIT, CREDIT
}
abstract class Transaction{
typeTransaction: TYPE_TRANSACTION;
montant: number;
soldeApres: number;
moment: Date;
constructor(typeTransaction: TYPE_TRANSACTION, montant: number, soldeApres: number){
this.typeTransaction = typeTransaction;
this.montant = montant;
this.soldeApres = soldeApres;
this.moment = new Date();
}
}
class Debit extends Transaction{
constructor(montant: number, soldeApres: number){
super(TYPE_TRANSACTION.DEBIT,montant, soldeApres);
}
}
class Credit extends Transaction{
constructor(montant: number, soldeApres: number){
super(TYPE_TRANSACTION.CREDIT,montant, soldeApres);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment