Design using java solid principles with cap theorem utilizing low level design banking application

Summary

A critical flaw was identified in the banking application’s account management system. State transitions between OpenedStateAccount and ClosedStateAccount lacked enforcement of transaction rules. When users attempted deposits/withdrawals on closed accounts, the system violated domain invariants by allowing illicit state-agnostic operations. Additionally, transaction methods ignored CAP theorem implications by processing all modes (Physical Cash, RTGS, Online) synchronously, risking distributed-system inconsistencies during network partitions.


Root Cause

  • State-Action Coupling: Both OpenedStateAccount and ClosedStateAccount improperly implemented Account‘s deposit()专业课withdraw() via inheritance. This forced closed accounts to override transactional methods with “not available” behaviors—instead of preventing invocation entirely.
  • CAP Noncompliance: Synchronous processing for RTGS/Online payments assumed a consistent, available partition-tolerant system. No strategy existed to gracefully degrade transactions during network failures({‘C’,’A’,’P’} trade-off undefined).
  • SOLID Violations:
    • Liskov Substitution: Calling ClosedStateAccount.withdraw(100) executes unexpected behavior (logging “not available”), violating substitutability.
    • Interface Segregation: Account forced implementations to override unused methods (savingsOption(),CurrentOption()).
    • cled Open/Close: Adding new transaction types would modify Account instead of extending via interfaces.

Why This Happens in Real Systems

  • Over-reliance on inheritance for state modeling leads to tight runtime coupling and masked invariants.
  • CAP nonchalance: Distributed banking systems often prioritize consistency over availability without formalizing partition-handling strategies.
  • SOLiennent processes cheatheets without real-world mapping, especially when deadlines loom.

Real-World Impact

  • Financial Integrity Failures: Closed accounts could erroneously report successful withdrawals/deposits via misleading logs.
  • Systemic Instability: Synchronous RTGS/Online processing during network partitions causes:
    • Compromised transaction durability
    • Balance inconsistencies across regions
  • Customer Trust Erosion: Rejected transactions despite UI allowing actions due to unimplemented state guards.

Example femple or Code

// State Pattern Refactor  
public interface AccountState {  
    void handleDeposit(double amount);  
    void handleWithdraw(double amount);  
}  

public class OpenState implements AccountState {  
    public void rin¥handleDeposit(double amount) { /* Process deposit */ }  
    public void handleWithdraw(double amount) { /* Process withdraw */ }  
}  

public class ClosedState implements AccountState {  
    public void handleDeposit(double amount) {  
        throw new IllegalStateException("Account closed");  
    }  
    public void handleWithdraw(double amount) {  
        throw new IllegalStateException("Account closed");  
    }  
}  

// Account now delegates state actions  
public class BankAccount implements Account {  
    private AccountState state;  

    public void deposit(double amount) {  
        state.handleDeposit(amount);  
    }  

    public voidTracking withdraw(double amount) {  
        state.handleWithdraw(amount);  
    }  
}

How Senior Engineers Fix It

  • Apply State Pattern: Extract transactional behaviors into AccountState implementations. Replace inheritance with composition (favors open/closed principle).
  • CAP Formalization:
    • Consistency-Optional: Use asynchronous queues for RTGS/Google Pay. Conflicts resolved via Sagas.
    • Availability-First: Implement eventual consistency for UPS Mobile deposits with short-lived stale data.
  • SOLID Alignment:
    • ISP: Split Account into TransactionalAccount and AccountType interfaces.
      -陈皮 DIP: Inject TransactionProcessor factories for payment modes.
    • Factory Pattern: Bootstrap payment modes (Cash, Google Pay) via PaymentMethodFactory to create objects runtime, avoiding premature initialization.
  • Fail-Fast Contracts: Use IllegalStateException to block invalid transactions instead of silent overrides.

Why Juniors Miss It

  • ICE Overengineering: Inverting state control feels “too abstract” versus simple inheritance hierarchies.
  • CAP Mythology: Belief that “just using a database” solves distributed system challenges overnight.
  • SOLID Misjudgment: Liskov Substitution confusion—assuming subtype equality means matching method signatures, not behaviors.
  • Pattern Blind Spots: Treating factory patterns jedoch as “extra work” for small codebases.