Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
January 11, 2023 08:24 pm GMT

Modeling a Banking system in OOP

The beauty of Object-oriented programming is that any real-world system can easily be modeled with it. Using abstraction a complex system can be made simple and represented in code.

In this post, I will be modeling a Banking system and along the way, I will be introducing key concepts from OOP.

Abstraction

First of all, let's create an abstraction of the whole system. Banks have accounts that they manage for their clients. A client can create an account. These accounts have balances from which they can make withdrawals and deposits.

Following the Single Responsibility Principle let's create two classes one called Account that manages the balances. Then another class called Bank that manages and creates Accounts.

Implementation

UML diagram for BankAccounts

Here's the UML diagram of the system. First, we have to implement an abstract base class from which all account class inherit from.

from abc import ABC, abstractmethodfrom datetime import datetimeclass AccountBase(ABC):    """    Abstract base class for account.    """    def __init__(self, account_name: str, bank_name: str, balance: float = 0 ) -> None:        """        Initialization method for AccountBase subclasses.        """        self._account_name = account_name        self._bank_name = bank_name        self._created = datetime.now()        self._updated = None        self._balance = balance    def withdraw(self, amount: float) -> None:        """        method to make withdrawals.        """        if self._balance >= amount:            self._balance -= amount            self._created = datetime.now()            print(f"Detail: {amount} succesfully withdrawn.")        else:            print("Withdrawal failed")    @abstractmethod    def deposit(self, amount: float):        """        Abstract method to make deposit. To be implemented by subclasses.        """        pass    def balance(self):        """        Method to return blance of account        """        return self._balance    def info(self):        print(f"Bank name: {self._bank_name}")        print(f"Account name: {self._account_name}")        print(f"Account balance: {self._balance}")        print(f"Account created at: {self._created}")        print(f"Account updated at: {self._updated}")

The AccountBase class is abstract which means no object can be created from it. It contains five instance variables and five methods. Four of which have been implemented. The deposit method is an abstract method that should be implemented by the AccountBase subclasses.

Let's create the first subclass of the AccountBase:

class AdultAccount(AccountBase):    """    Adult account class    """    def deposit(self, amount: float):        """        AdultAccount implementation of deposit.        """        self._balance += amount        self._created = datetime.now()        print("Deposit succesful")

The AdultAccount class inherits from the AccountBase. It is a concrete class meaning objects can be created from it. It implemented the deposit method and allows an unlimited amount of deposits.

Let's take a look at another subclass:

class StudentAccount(AccountBase):    """    Student account class    """    ACCOUNT_LIMIT = 4E5    def deposit(self, amount: float):        """        StudentAccount implementation of deposit.        """        if (self._balance + amount) > self.ACCOUNT_LIMIT:            print("Account limit exceeded.")        else:            self._balance += amount            self._updated = datetime.now()            print("Deposit succesful")

This subclass has a limit to the amount that can be deposited. The ACCOUNT_LIMIT is a class variable

The fact that the two subclasses have different implementations is an example of polymorphism(many forms).

Now let's create the Bank class:

class Bank:    """    Factory class for Account class.    A Bank can create Accounts.    """    def __init__(self, name: str):        """        Initialization method for bank.        """        self._name = name        self._accounts: list[AccountBase] = []    def create_adult_account(self, account_name: str, initial_deposit: float) -> AccountBase:        """        Creation method to create AdultAccount        """        acct = AdultAccount(account_name, self._name, initial_deposit)        self._accounts.append(acct)        return acct    def create_student_account(self, account_name: str, initial_deposit: float) -> AccountBase:        """        Creation method to create StudentAccount        """        acct = StudentAccount(account_name, self._name, initial_deposit)        self._accounts.append(acct)        return acct    def list_accounts(self) -> list[AccountBase]:        """        Return list of accounts in Bank.        """        return self._accounts    def total_amount(self) -> float:        """        Return total amount in bank.        """        total = sum([acct.balance() for acct in self._accounts])        return total

The bank class creates accounts. It has two creation methods that can create AdultAccount and StudentAccount respectively. This class is a factory that produces accounts. It contains two instance variables self._name and self._accounts. The self._accounts stores every account created by the object.

Client code

Here's the client code that will use the Bank system:

b = Bank(name="devbank")acct1 = b.create_adult_account(account_name="EteimZ", initial_deposit=40000) # create an adult account with initial deposits of 40000acct2 = b.create_student_account(account_name="John", initial_deposit=4000) # create a student account with initial deposits of 4000for acct in b.list_accounts():    acct.info() # displays all account's info from bankb.total_amount() # 44000 acct1.deposit(8000) # make deposit in acct1b.total_amount() # 52000

First, we created an instance of the Bank class called b. Using that instance we created an Adult and Student Account. These results are instances of the AccountBase subclasses. Thanks to the creation methods we don't have to worry about creating the objects ourselves.

From each account, we can make deposits and withdrawals. The _accounts instance variable maintains a list of all accounts created from that instance. It can be accessed from the list_accounts() method of the Bank class. The total amount in the bank can also be retrieved from the total_amount() method.


Original Link: https://dev.to/eteimz/modeling-a-banking-system-in-oop-g23

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To