This solution has been refactored to make the payment flow easier to reason about, easier to test, and closer to SOLID principles.
PaymentServicenow acts mainly as an orchestrator for the payment flow instead of containing every payment rule.- Payment validation rules were split into separate strategy classes:
BacsPaymentStrategyChapsPaymentStrategyFasterPaymentsPaymentStrategy
- Data store creation was moved behind
IAccountDataStoreFactory/AccountDataStoreFactory. - Unit tests were added for:
PaymentService- each payment strategy
- the account data store factory
- Separating the payment rules by scheme gives each class a single responsibility and makes the rules easier to extend without growing
PaymentService. - Injecting abstractions such as the payment strategy and data store factory makes the service easier to isolate in tests.
- Testing each strategy independently keeps the payment rule tests small and focused.
- Testing
PaymentServiceseparately verifies the orchestration behavior: loading the account, validating the payment, updating the balance, and persisting the account when valid.
The result is a payment flow with clearer responsibilities, better unit-test coverage, and less coupling between payment rule logic, configuration, and persistence concerns.