How do I separate interface and implementation cleanly for financial apps?

In financial applications, separating interface and implementation is crucial for maintainability, scalability, and clarity. This approach allows developers to change the underlying logic without affecting the user experience.
C++, interface, implementation, financial applications, code architecture, software design, clean code

    // Interface for financial calculations
    class IFinancialCalculator {
        public:
            virtual double calculateInterest(double principal, double rate, int time) = 0;
            virtual double calculateLoanEMI(double principal, double rate, int term) = 0;
            virtual ~IFinancialCalculator() {}
    };

    // Implementation of the financial calculator
    class FinancialCalculator : public IFinancialCalculator {
        public:
            double calculateInterest(double principal, double rate, int time) override {
                return principal * rate * time / 100;
            }

            double calculateLoanEMI(double principal, double rate, int term) override {
                double monthlyRate = rate / (12 * 100);
                return (principal * monthlyRate * pow(1 + monthlyRate, term)) / (pow(1 + monthlyRate, term) - 1);
            }
    };

    // Usage of the interface and implementation
    int main() {
        IFinancialCalculator* calculator = new FinancialCalculator();
        double interest = calculator->calculateInterest(1000, 5, 2);
        double emi = calculator->calculateLoanEMI(50000, 10, 60);
        
        delete calculator;
        return 0;
    }
    

C++ interface implementation financial applications code architecture software design clean code