Shahrayar123 / Python-Projects

Basic Python projects, good first issue
272 stars 274 forks source link

Implement design patterns and add tests #212

Open onlyoneuche opened 4 weeks ago

onlyoneuche commented 4 weeks ago

Refactor banking script using design patterns and add unit tests

This PR refactors the banking script to follow several design patterns, improving its maintainability, testability, and extensibility. The following changes have been made:

  1. Implemented the Repository Pattern:

    • Introduced the CardRepository class to handle all database operations related to cards.
    • Separated the data access logic from the business logic, making the code more modular and easier to maintain.
  2. Applied the Factory Method Pattern:

    • Created an abstract CardFactory class and a concrete CreditCardFactory class.
    • Allows for the creation of different types of cards (e.g., credit cards, debit cards) with different rules and behaviors.
  3. Utilized the Strategy Pattern:

    • Introduced separate strategy classes for card number generation (CardNumberGenerator), PIN generation (PinGenerator), and card number validation (CardNumberValidator).
    • Each algorithm is encapsulated in a separate strategy class, making it easier to extend or replace the algorithms in the future.
  4. Improved the Card class:

    • Removed direct database interactions from the Card class.
    • Delegated responsibilities to the CardRepository and CardFactory classes, following the Single Responsibility Principle.
  5. Added comprehensive unit tests:

    • Implemented a test suite (test_card.py) to ensure the correctness of the refactored code.
    • Tests cover various scenarios, including account creation, logging in, balance management, money transfers, and account closure.
    • Tests utilize mocks and in-memory SQLite databases for isolation and reproducibility.

By following these design patterns, the codebase has become more modular, maintainable, and testable. The separation of concerns and the introduction of abstractions make it easier to extend or modify the functionality in the future. Additionally, the comprehensive unit tests provide a safety net for future changes and ensure the correct behavior of the application.