Software EngineeringUnit 613 min read
OO Design & Patterns: Classes, UML, SOLID, Gang of Four
Unit 6 of Software Engineering covers object-oriented design principles (encapsulation, inheritance, polymorphism), UML class diagrams, design patterns (creational, structural, behavioral), and their application in real-world systems like eSewa’s payment flow or Daraz’s order routing.
TAKEAWAYS:
- Classes and objects model real-world entities with attributes (data) and methods (behavior), visualized in UML class diagrams.
- Design patterns (e.g., Singleton, Observer, Factory) solve recurring problems in OO design, improving code reusability and maintainability.
- SOLID principles (Single Responsibility, Open/Closed, Liskov Substitution) ensure robust, scalable OO architectures.
- UML diagrams (class, sequence, state) bridge analysis and design, helping teams communicate system structure clearly.
- Real-world ties: Patterns like Observer power live updates in WhatsApp messages, while Strategy lets Pathao choose optimal delivery routes dynamically.
Core Concepts: Classes, Objects, and UML
1. Classes and Objects
Definition:
- A class is a blueprint for objects, defining attributes (data) and methods (functions). An object is an instance of a class.
- Example: In a banking system,
Accountis a class with attributesaccountNumber,balance, and methodsdeposit(),withdraw(). An object likeaccount123is a specific bank account.
Key Properties:
- Encapsulation: Bundling data and methods that operate on the data, restricting direct access via access modifiers (
private,public,protected). - Inheritance: A mechanism where a new class (child) inherits properties/methods from an existing class (parent). Example:
SavingsAccountinherits fromAccount. - Polymorphism: Objects of different classes can be treated as objects of a common superclass. Example: A
Shapeclass with methodsdraw()can have subclassesCircleandRectangle, each implementingdraw()differently.
UML Class Diagram:
classDiagram
class Account {
-accountNumber: String
-balance: Double
+deposit(amount: Double)
+withdraw(amount: Double)
}
class SavingsAccount {
-interestRate: Double
+calculateInterest()
}
Account <|-- SavingsAccountReal-world tie: In eSewa, the Payment class handles transactions, while MobilePayment (child of Payment) adds SMS-based authentication.
2. UML Diagrams for OO Design
UML (Unified Modeling Language) provides visual tools to model systems. For this unit, focus on:
- Class Diagrams: Show classes, their attributes, methods, and relationships (inheritance, association, aggregation, composition).
- Sequence Diagrams: Model interactions between objects over time (e.g., a user ordering from Daraz).
- State Diagrams: Represent object lifecycle (e.g., an order in Daraz:
Placed→Processing→Shipped).
Example: Daraz Order Processing (Sequence Diagram)
sequenceDiagram
participant User
participant Order
participant Payment
participant Inventory
User->>Order: placeOrder(itemList)
Order->>Payment: processPayment(amount)
Payment-->>Order: PaymentSuccess
Order->>Inventory: checkStock(itemList)
Inventory-->>Order: StockAvailable
Order->>User: confirmOrder(orderID)Real-world tie: Pathao’s ride-hailing system uses sequence diagrams to model driver-passenger interactions (e.g., User requests ride → Driver accepts → Navigation updates route).
SOLID Principles: Writing Maintainable Code
SOLID is an acronym for five design principles to improve OO design:
| Principle | Description | Example |
|---|---|---|
| Single Responsibility | A class should have one reason to change (one responsibility). | User class handles authentication; Order class manages orders. |
| Open/Closed | Classes should be open for extension but closed for modification. | Use inheritance/interface to add features (e.g., Payment interface with CreditCardPayment, MobilePayment). |
| Liskov Substitution | Subclasses must be substitutable for their parent classes without breaking behavior. | A Square class should not break Rectangle methods (e.g., area()). |
| Interface Segregation | Clients should not be forced to depend on interfaces they don’t use. | Split IPayment into ICreditCardPayment and IMobilePayment. |
| Dependency Inversion | High-level modules should not depend on low-level modules; both should depend on abstractions. | OrderProcessor depends on IPayment, not CreditCardPayment directly. |
Worked Example: Ncell’s Billing System
- Problem: The
Billingclass handles bothPrepaidandPostpaidplans, violating Single Responsibility. - Solution: Refactor into:
classDiagram
class Billing {
+generateBill(user: User)
}
class Plan {
<<interface>>
+calculateBill(usage: Double)
}
class PrepaidPlan {
+calculateBill(usage: Double)
}
class PostpaidPlan {
+calculateBill(usage: Double)
}
Billing --> Plan
PrepaidPlan ..|> Plan
PostpaidPlan ..|> Plan- Benefit: Adding a new plan (e.g.,
CorporatePlan) requires extendingBillingwithout modifying it.
Design Patterns: Reusable Solutions
Design patterns are proven solutions to common OO problems. They are categorized into three groups:
1. Creational Patterns
Purpose: Handle object creation.
| Pattern | Use Case | Example |
|---|---|---|
| Singleton | Ensure a class has only one instance (e.g., configuration manager). | DatabaseConnection in eSewa to manage a single DB link. |
| Factory | Delegate object creation to subclasses. | PaymentFactory creates CreditCardPayment or MobilePayment objects. |
| Builder | Construct complex objects step-by-step. | OrderBuilder in Daraz to assemble orders with items, addresses, etc. |
Singleton Example (eSewa’s Config Manager):
public class ConfigManager {
private static ConfigManager instance;
private Properties config;
private ConfigManager() { config = loadConfig(); }
public static ConfigManager getInstance() {
if (instance == null) {
instance = new ConfigManager();
}
return instance;
}
}
2. Structural Patterns
Purpose: Organize relationships between classes.
| Pattern | Use Case | Example |
|---|---|---|
| Adapter | Make incompatible interfaces work together. | LegacyPaymentAdapter to integrate old payment systems with eSewa. |
| Decorator | Add responsibilities to objects dynamically. | EncryptedOrder decorator adds encryption to Order objects. |
| Facade | Simplify complex subsystems. | PaymentFacade in Khalti to hide low-level payment processing. |
Decorator Example (Daraz Order Encryption):
3. Behavioral Patterns
Purpose: Define communication between objects.
| Pattern | Use Case | Example |
|---|---|---|
| Observer | Notify objects of state changes (e.g., event handling). | WhatsApp notifies users of new messages via Observer pattern. |
| Strategy | Encapsulate interchangeable algorithms. | Pathao uses DeliveryStrategy to choose fastest/cheapest route. |
| Command | Encapsulate requests as objects. | Daraz’s PlaceOrderCommand to undo/redo orders. |
Observer Example (WhatsApp Messages):
classDiagram
class Message {
-observers: List~Observer~
+attach(observer: Observer)
+notify()
}
class User {
+update(message: String)
}
Message "1" *-- "0..*" User : observesReal-world tie: NEPSE’s stock price updates use the Observer pattern to notify subscribers of price changes.
Comparing Patterns and SOLID
| Feature | Design Patterns | SOLID Principles |
|---|---|---|
| Scope | Specific solutions to common problems. | Broad guidelines for good OO design. |
| Example | Singleton, Observer. | Single Responsibility, Open/Closed. |
| When to Use | When you need a proven solution. | When designing classes/interfaces. |
| Focus | Behavior/structure of objects. | Principles for maintainable code. |
Worked Example: Kathmandu Traffic Routes (Strategy Pattern)
- Problem: Traffic routes change based on time/day (e.g., rush hour vs. night).
- Solution: Use
RouteStrategyinterface with implementations:interface RouteStrategy { String calculateRoute(); } class RushHourStrategy implements RouteStrategy { ... } class NightStrategy implements RouteStrategy { ... } - Benefit: Switch strategies dynamically without modifying route logic.
UML in Practice: Modeling a System
Case Study: Khalti Payment Flow
- Class Diagram:
classDiagram class User { +id: String +balance: Double } class Payment { +amount: Double +process() } class MobilePayment { +phoneNumber: String +authenticate() } User "1" --> "1" Payment Payment <|-- MobilePayment - Sequence Diagram (Payment Process):
sequenceDiagram participant User participant KhaltiApp participant PaymentGateway User->>KhaltiApp: InitiatePayment(amount) KhaltiApp->>PaymentGateway: RequestPayment(amount) PaymentGateway-->>KhaltiApp: PaymentSuccess/Failed KhaltiApp->>User: ShowResult()
Real-world tie: NTC’s billing system uses UML to model interactions between Customer, Bill, and Payment classes.
In the Real World
eSewa’s Payment System:
- Uses the Observer pattern to notify users of transaction status updates (e.g.,
PaymentSuccess,PaymentFailed). - Applies Singleton for the
ConfigManagerto ensure consistent settings across all transactions.
- Uses the Observer pattern to notify users of transaction status updates (e.g.,
Pathao’s Route Optimization:
- Employs the Strategy pattern to dynamically select the best delivery route based on traffic, distance, or driver availability.
- Follows Open/Closed Principle to add new route algorithms (e.g.,
EcoRouteStrategy) without modifying existing code.
Daraz’s Order Processing:
- Uses Builder pattern to construct complex orders with items, addresses, and payment details step-by-step.
- Implements Facade pattern to simplify the checkout process for users (hiding underlying inventory/payment systems).
Exam Tip
- Diagrams are worth marks: Always draw UML class/sequence diagrams for case studies. Label relationships (e.g., inheritance, association) and include attributes/methods.
- Pattern applications: For questions like “How would you design X?”, tie your answer to 1–2 patterns (e.g., “Use Observer for live updates in WhatsApp”).
- SOLID violations: Exams often ask to “Identify and fix SOLID violations”. Practice refactoring code snippets (e.g., splitting a monolithic class).
- Real-world mapping: Relate abstract concepts to local apps (e.g., “Khalti uses Decorator to add fraud checks to payments”).
- Trace examples: For sequence diagrams, trace the flow step-by-step (e.g., “User → Order → Payment → Inventory → User”).
Based on the PU BE Computer (PU) syllabus for Software Engineering (CMP348), unit 6.
Discussion
Loading…