Elective Object Oriented Programming in C++

Object Oriented Programming in C++Unit 1113 min read

OOAD: CRC Cards, UML Diagrams, Design Principles & Real-World Systems

Unit 11 of Object Oriented Programming in C++ covers Object-Oriented Analysis and Design (OOAD) techniques—CRC cards, UML diagrams (class, sequence, use-case), design principles (SOLID, DRY), and how to model real-world systems like eSewa’s payment flow or Daraz’s order processing. Learn to decompose problems into reus

TAKEAWAYS:

  • CRC cards break down system responsibilities into classes, roles, and collaborations—critical for designing modular systems like Khalti’s payment gateway.
  • UML diagrams (class, sequence, use-case) visually model interactions: Pathao’s ride-booking system uses sequence diagrams to show driver-passenger communication.
  • Design principles (SOLID, DRY) prevent code duplication and improve maintainability—Nepal Rastra Bank’s loan system follows Open/Closed Principle for adding new loan types.
  • Responsibility-Driven Design (RDD) assigns tasks to objects based on their expertise, reducing coupling—NTC’s billing system uses RDD to separate Customer, Bill, and Payment logic.
  • Substitutability (Liskov Substitution Principle) ensures derived classes can replace base classes—NEPSE’s stock trading system uses this for Broker and Trader hierarchies.
  • Non-linear complexity in OOAD arises from interactions between objects—WhatsApp’s end-to-end encryption relies on complex object collaborations for security.

1. Why OOAD? Procedure-Oriented vs. Object-Oriented Programming

OOAD is the bridge between problem analysis and C++ implementation. Unlike procedure-oriented programming (POP), which focuses on functions and data separation, OOAD encapsulates data and behavior into objects, leading to:

  • Modularity: Components are independent and reusable (e.g., eSewa’s User class works for both payments and profile management).
  • Scalability: New features (e.g., Daraz’s "Cash on Delivery") can be added without rewriting core logic.
  • Maintainability: Changes in one class (e.g., Ncell’s Billing class) don’t ripple through unrelated code.

Comparison Table: POP vs. OOP

Feature Procedure-Oriented Programming (POP) Object-Oriented Programming (OOP)
Focus Functions and data separation Objects (data + behavior)
Data Access Global or passed as arguments Encapsulated within classes
Reusability Low (functions are independent) High (inheritance, polymorphism)
Complexity Handling Linear (functions call functions) Non-linear (objects interact dynamically)
Example C-style calculateSalary(emp) C++ Employee class with calculateSalary()

2. CRC Cards: The Blueprint for Classes

CRC (Class-Responsibility-Collaborator) cards are index cards that define:

  • Class Name: What the object represents (e.g., Order in Daraz).
  • Responsibilities: What the object knows/does (e.g., calculateTotal(), updateStatus()).
  • Collaborators: Other objects it interacts with (e.g., Payment, Inventory).

Example: eSewa Payment System

classDiagram
    class User {
        +makePayment(amount)
        +viewTransactionHistory()
    }
    class Payment {
        +processPayment(user, amount)
        +verifyOTP()
    }
    class Bank {
        +deductFunds(amount)
        +creditFunds(amount)
    }
    User --> Payment : "uses"
    Payment --> Bank : "collaborates"

Worked Example: Designing a Library System

  1. Classes:
    • Book (title, author, ISBN)
    • Member (name, membershipID)
    • Library (manage books/members)
  2. CRC for Library:
    • Responsibilities:
      • Add/remove books.
      • Issue/return books to members.
    • Collaborators: Book, Member.

3. UML Diagrams: Visualizing Object Interactions

UML (Unified Modeling Language) diagrams model systems graphically. Key diagrams for OOAD:

A. Class Diagram

Shows classes, attributes, methods, and relationships. Example: NTC Billing System

classDiagram
    class Customer {
        -name: String
        -connectionID: String
        +calculateBill(units)
    }
    class Bill {
        -amount: double
        -dueDate: Date
        +generatePDF()
    }
    class Payment {
        +processPayment(amount)
    }
    Customer "1" --> "1..*" Bill : "has"
    Bill --> Payment : "requires"

Key Symbols:

  • - = private, + = public
  • 1..* = one-to-many relationship

B. Sequence Diagram

Shows object interactions over time (e.g., Pathao’s ride request flow). Example: Ordering Food on Pathao

sequenceDiagram
    participant User
    participant PathaoApp
    participant Restaurant
    participant Driver

    User->>PathaoApp: placeOrder(foodItems)
    PathaoApp->>Restaurant: confirmOrder()
    Restaurant-->>PathaoApp: orderConfirmed()
    PathaoApp->>Driver: assignOrder()
    Driver->>PathaoApp: orderAccepted()
    PathaoApp-->>User: orderStatusUpdated()

C. Use-Case Diagram

Shows actors and their interactions (e.g., NEPSE trading system). Example: Stock Trading

classDiagram
    actor Trader
    actor Broker
    class BuyStock {
        <<useCase>>
        +executeTrade()
    }
    class SellStock {
        <<useCase>>
        +executeTrade()
    }
    Trader --> BuyStock
    Trader --> SellStock
    Broker --> BuyStock
    Broker --> SellStock

4. Responsibility-Driven Design (RDD)

RDD is an iterative process to assign responsibilities to objects:

  1. Identify core responsibilities (e.g., "Track orders" in Daraz).
  2. Assign to the most informed object (e.g., Order class knows its status).
  3. Refine collaboratively (e.g., Payment handles transactions).

Example: Kathmandu Traffic Management

  • Problem: Traffic lights must coordinate with sensors and police.
  • Solution:
    • TrafficLight (responsible for changing signals).
    • Sensor (detects congestion).
    • Police (overrides signals in emergencies).

5. Design Principles: SOLID and DRY

A. SOLID Principles

Principle Description Example (Nepal Context)
Single Responsibility A class should have one reason to change. User class handles only authentication, not billing.
Open/Closed Open for extension, closed for modification. Loan base class; HomeLoan and CarLoan extend it.
Liskov Substitution Derived classes must replace base classes without breaking code. ElectricVehicle can replace Vehicle in NTC’s fleet.
Interface Segregation Clients shouldn’t depend on unused methods. Separate PaymentInterface for CreditCard and Cash.
Dependency Inversion Depend on abstractions, not concretions. Bank depends on PaymentGateway interface, not Khalti class.

B. DRY (Don’t Repeat Yourself)

  • Problem: Duplicate code is hard to maintain (e.g., Ncell’s duplicate billing logic).
  • Solution: Use inheritance or composition.
    // Bad: Duplicate login code
    void loginUser() { /* ... */ }
    void adminLogin() { /* duplicate code */ }
    
    // Good: Base class
    class User {
    public:
        void login() { /* shared logic */ }
    };
    class Admin : public User { /* extends */ };
    

6. Non-Linear Complexity in OOAD

Unlike POP (where complexity grows linearly with functions), OOAD’s complexity is non-linear due to:

  • Object interactions (e.g., WhatsApp’s encryption involves Message, KeyManager, Server).
  • Inheritance hierarchies (e.g., Nepal Rastra Bank’s Loan → PersonalLoan → EducationLoan).
  • Polymorphism (e.g., Daraz’s PaymentMethod interface used by CreditCard, CashOnDelivery).

Visualizing Complexity:

graph TD
    A["OOAD System"] --> B["Objects"]
    A --> C["Relationships"]
    A --> D["Inheritance"]
    B --> E["Linear: Each object's methods"]
    C --> F["Non-linear: Interactions between objects"]
    D --> G["Non-linear: Deep hierarchies"]
    F --> H["Example: WhatsApp's E2E Encryption"]
    G --> I["Example: NEPSE's Trader Hierarchy"]

7. Real-World Applications

A. eSewa: Payment Gateway

  • CRC Cards:
    • User: Responsibilities = login(), viewBalance(); Collaborators = Payment, Transaction.
    • Payment: processPayment(), verifyOTP(); Collaborators = Bank, User.
  • UML Class Diagram:
    classDiagram
        class User {
            -walletBalance: double
            +login()
        }
        class Payment {
            +process(amount, method)
        }
        class Bank {
            +transfer(amount, toAccount)
        }
        User --> Payment : "initiates"
        Payment --> Bank : "executes"

B. Daraz: Order Processing

  • Sequence Diagram for Order Flow:
    sequenceDiagram
        participant User
        participant Daraz
        participant Inventory
        participant Payment
    
        User->>Daraz: selectProducts()
        Daraz->>Inventory: checkStock()
        Inventory-->>Daraz: stockAvailable()
        Daraz->>Payment: processPayment()
        Payment-->>Daraz: paymentSuccess()
        Daraz-->>User: orderConfirmed()

C. NTC: Billing System

  • Design Principle Applied:
    • Open/Closed: Bill class extended to ElectricityBill and InternetBill.
    • Single Responsibility: Customer handles only profile; Billing handles calculations.

8. Worked Example: Designing a Bank Loan System

Requirements:

  • Loan base class with calculateInterest().
  • Derived classes: HomeLoan, CarLoan.
  • Customer applies for loans.

Step 1: CRC Cards

Class Responsibilities Collaborators
Loan Calculate interest rate Customer
HomeLoan Apply home loan rules Loan
Customer Apply for loan, view loan status Loan, Bank

Step 2: UML Class Diagram

classDiagram
    class Loan {
        <<abstract>>
        -principal: double
        -interestRate: double
        +calculateInterest()
    }
    class HomeLoan {
        +calculateInterest() override
    }
    class CarLoan {
        +calculateInterest() override
    }
    class Customer {
        -name: String
        -loanHistory: List~Loan~
        +applyLoan(loanType)
    }
    Loan <|-- HomeLoan
    Loan <|-- CarLoan
    Customer --> Loan : "applies"

Step 3: C++ Implementation

#include <iostream>
using namespace std;

class Loan {
protected:
    double principal;
    double interestRate;
public:
    Loan(double p, double rate) : principal(p), interestRate(rate) {}
    virtual double calculateInterest() = 0; // Pure virtual
};

class HomeLoan : public Loan {
public:
    HomeLoan(double p) : Loan(p, 0.08) {} // 8% interest
    double calculateInterest() override {
        return principal * interestRate;
    }
};

class Customer {
    string name;
    Loan* loan;
public:
    void applyLoan(Loan* l) { loan = l; }
    void displayInterest() {
        cout << "Interest: " << loan->calculateInterest() << endl;
    }
};

int main() {
    Customer c;
    Loan* homeLoan = new HomeLoan(1000000);
    c.applyLoan(homeLoan);
    c.displayInterest(); // Output: Interest: 80000
    delete homeLoan;
    return 0;
}

Step 4: Trace Table

Step Action principal interestRate Output
1 HomeLoan(1000000) created 1,000,000 0.08
2 c.applyLoan(homeLoan) 1,000,000 0.08
3 c.displayInterest() 1,000,000 0.08 Interest: 80000

9. Exam Tip: How to Score Full Marks

  1. For CRC Cards:

    • Always list 3 clear responsibilities and 2 collaborators.
    • Example: For Library, mention Book and Member as collaborators.
  2. For UML Diagrams:

    • Label all relationships (e.g., 1..* for one-to-many).
    • Use <<interface>> for abstract classes (e.g., PaymentMethod).
  3. For Design Principles:

    • SOLID: Give a Nepalese example (e.g., "Nepal Rastra Bank uses Open/Closed for new loan types").
    • DRY: Show before/after code snippets to highlight duplication.
  4. For Short Notes:

    • OOAD: Define as "a methodology to model systems as interacting objects using UML and design principles."
    • STL: Mention vector, map, and algorithm headers.
  5. For Programming Questions:

    • Always include:
      • Class diagrams (even in text, describe relationships).
      • Trace tables for loops/conditionals.
      • Error handling (e.g., try-catch for invalid loan amounts).

10. Common Pitfalls to Avoid

  • Overloading responsibilities: Don’t put calculateTax() in Customer—use Billing.
  • Tight coupling: Avoid Bank directly calling Khalti methods; use interfaces.
  • Ignoring collaborators: Always specify which objects interact in CRC cards.
  • Skipping UML details: Exams often ask for arrows, multiplicities, and access modifiers.

Based on the PU BE Computer (PU) syllabus for Object Oriented Programming in C++, unit 11.

Discussion

Loading…