Skip to content

Object-Oriented Analysis and Design

Object-Oriented Analysis and Design (OOAD) is a structured method for analyzing and designing systems by applying object-oriented concepts. This guide covers fundamental OO principles, UML diagrams, and the relationships between classes.

Problem: When class A directly uses class B, any method changes in class B (e.g., classB.method1()classB.method2()) require updates in class A.

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #ef4444
skinparam classBackgroundColor #fee2e2
skinparam classBorderColor #ef4444
class ClassA {
- objectB: ClassB
+ doSomething()
}
class ClassB {
+ method1()
}
ClassA --> ClassB : "Tight Coupling"
note right of ClassA::doSomething
objectB.method1()
// If ClassB changes method1 to method2,
// ClassA must be updated!
end note
note "Changes in ClassB\nrequire changes in ClassA" as N1
@enduml

Solution: Use interfaces to decouple dependencies. Class A refers to class B through an interface C, so changes in class B’s implementation don’t impact class A.

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam rectangleBorderColor #64748b
skinparam classBackgroundColor #f0fdf4
skinparam classBorderColor #22c55e
skinparam interfaceBackgroundColor #ecfdf5
skinparam interfaceBorderColor #10b981
class ClassA {
- objectC: InterfaceC
+ doSomething()
}
interface InterfaceC {
+ execute()
}
class ClassB {
+ execute()
}
ClassA --> InterfaceC : "Loose Coupling"
InterfaceC <|-- ClassB : implements
note right of ClassA::doSomething
objectC.execute()
// ClassA doesn't know about ClassB!
// Changes in ClassB won't affect ClassA
end note
note "ClassA depends on abstraction,\nnot concrete implementation" as N1
@enduml

The process of Object-Oriented Analysis and Design involves investigating the objects that constitute a system and determining how they interact.

  1. Identify the objects in a system
  2. Define relationships between objects
  3. Establish the interface of each object
  4. Create a design that can be converted to executables using OO languages

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
!define STEP_COLOR #dbeafe
!define STEP_BORDER #3b82f6
rectangle "1. Identify Objects" as step1 STEP_COLOR
rectangle "2. Define Relationships" as step2 STEP_COLOR
rectangle "3. Establish Interfaces" as step3 STEP_COLOR
rectangle "4. Create Executable Design" as step4 STEP_COLOR
step1 -down-> step2
step2 -down-> step3
step3 -down-> step4
note right of step1
What are the entities
in the system?
end note
note right of step2
How do objects
interact?
end note
note right of step3
What methods and
properties?
end note
note right of step4
Implementation-ready
design
end note
@enduml

UML is a way of visualizing and documenting a software system using a collection of diagrams, helping engineers, businesspeople, and system architects understand the behavior and structure of the system being designed.

There are 14 different kinds of UML diagrams, classified into two main groups:

Diagram TypePurpose
Class DiagramDescribes structure and behavior in use cases, providing a conceptual model in terms of entities and their relationships
Component DiagramShows how components are organized and their dependencies
Object DiagramShows a snapshot of objects and their relationships at a specific time
Package DiagramShows dependencies between packages
Diagram TypePurpose
Use Case DiagramDescribes user scenarios and illustrates the functionality provided by the system
Sequence DiagramDescribes interactions among classes in terms of message exchange over time
Activity DiagramModels the functional flow-of-control between two or more class objects
State DiagramShows the different states of an object throughout its lifecycle

A class is depicted as a rectangle with three horizontal sections:

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class ClassName {
- privateAttribute: Type
# protectedAttribute: Type
+ publicAttribute: Type
__
- privateMethod(): ReturnType
# protectedMethod(): ReturnType
+ publicMethod(): ReturnType
{static} + staticMethod(): ReturnType
{abstract} + abstractMethod(): ReturnType
}
note right of ClassName
**Top Section:** Class Name
**Middle Section:** Attributes (fields)
**Bottom Section:** Methods (operations)
**Visibility Markers:**
+ public
- private
# protected
~ package/default
end note
note left of ClassName::privateAttribute
Attributes define
the state of the class
end note
note left of ClassName::publicMethod
Methods define
the behavior
end note
@enduml

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class Flight {
- flightNumber: String
- departureTime: DateTime
- arrivalTime: DateTime
+ getFlightNumber(): String
+ schedule(): void
}
class Aircraft {
- model: String
- capacity: int
+ getCapacity(): int
}
class Pilot {
- name: String
- licenseNumber: String
+ fly(): void
}
class FlightInstance {
- date: Date
- status: String
+ updateStatus(): void
}
class Airline {
- name: String
- code: String
+ addFlight(): void
}
Flight --> Aircraft : "uses >"
Flight "1" -- "2..*" Pilot : "requires >"
Flight "1" -- "*" FlightInstance : "has >"
Airline o-- Flight : "owns >"
@enduml

Definition: A link between classes that need to communicate with each other.

  • Uni-directional (with arrow): Only one party is aware of the relationship
  • Bi-directional (no arrow): Both entities are aware of the relationship

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class Pilot {
- name: String
+ fly(): void
}
class FlightInstance {
- date: Date
+ assignPilot(): void
}
class Flight {
- flightNumber: String
}
class Aircraft {
- model: String
}
Pilot -- FlightInstance : "Bi-directional"
Flight --> Aircraft : "Uni-directional"
note right of FlightInstance
Both Pilot and FlightInstance
know about each other
end note
note right of Aircraft
Only Flight knows
about Aircraft
end note
@enduml

Definition: Specifies how many instances of a class can participate in a relationship.

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class FlightInstance {
- date: Date
}
class Pilot {
- name: String
}
class Passenger {
- ticketNumber: String
}
FlightInstance "1" -- "2..*" Pilot : "requires"
FlightInstance "1" -- "0..*" Passenger : "carries"
note bottom of FlightInstance
**Multiplicity Notations:**
1 = exactly one
0..1 = zero or one
* = zero or many
0..* = zero or many
1..* = one or many
2..* = two or many
5 = exactly 5
end note
@enduml

Example: Aircraft can exist without Airline. Books can exist without Library.

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class Library {
- name: String
+ addBook(): void
}
class Book {
- isbn: String
- title: String
}
class Car {
- model: String
}
class Wheel {
- size: int
}
class Airline {
- name: String
}
class Aircraft {
- model: String
}
Library o-- Book : "has"
Car o-- Wheel : "has"
Airline o-- Aircraft : "owns"
note right of Book
Books can exist
independently of Library
end note
note right of Aircraft
Aircraft can be
reassigned to
another Airline
end note
@enduml

Example: WeeklySchedule cannot exist without Flight. TransactionHistory cannot exist without BankAccount.

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class Flight {
- flightNumber: String
}
class WeeklySchedule {
- days: List<String>
}
class BankAccount {
- accountNumber: String
}
class TransactionHistory {
- transactions: List
}
class ParkingFloor {
- floorNumber: int
}
class ParkingSpot {
- spotId: String
}
Flight *-- WeeklySchedule : "contains"
BankAccount *-- TransactionHistory : "owns"
ParkingFloor *-- ParkingSpot : "composed of"
note right of WeeklySchedule
WeeklySchedule dies
when Flight is destroyed
end note
note right of TransactionHistory
TransactionHistory cannot
exist without BankAccount
end note
note right of ParkingSpot
If ParkingFloor is removed,
all ParkingSpot instances
are automatically removed
end note
@enduml

Example: Crew, Pilot, and Admin are all Person. Dog IS-A Animal, Cat IS-A Animal.

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class Person {
- name: String
- age: int
+ getDetails(): String
}
class Crew {
- crewId: String
+ assignDuty(): void
}
class Pilot {
- licenseNumber: String
+ fly(): void
}
class Admin {
- department: String
+ manage(): void
}
class Animal {
- species: String
+ eat(): void
}
class Dog {
+ bark(): void
}
class Cat {
+ meow(): void
}
Person <|-- Crew
Person <|-- Pilot
Person <|-- Admin
Animal <|-- Dog
Animal <|-- Cat
note right of Person
Parent/Base class
(Generalization)
end note
note bottom of Pilot
Pilot IS-A Person
Inherits all Person
attributes and methods
end note
@enduml

Example: FlightReservation depends on Payment. Driver uses Vehicle.

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class FlightReservation {
- reservationId: String
+ processPayment(Payment): boolean
}
class Payment {
- amount: double
+ validate(): boolean
}
class Driver {
+ drive(Vehicle): void
}
class Vehicle {
+ accelerate(): void
}
class Admin {
+ addParkingFloor(ParkingFloor): void
}
class ParkingFloor {
- floorNumber: int
}
FlightReservation ..> Payment : "depends on"
Driver ..> Vehicle : "uses"
Admin ..> ParkingFloor : "uses"
note right of FlightReservation
FlightReservation uses
Payment as a parameter
(weak dependency)
end note
note right of Driver
Driver accepts Vehicle
as method parameter
end note
@enduml

Abstract Class: Identified by name in italics. Cannot be instantiated.

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 13
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
skinparam interfaceBackgroundColor #ecfdf5
skinparam interfaceBorderColor #10b981
abstract class Shape {
# color: String
+ {abstract} calculateArea(): double
+ setColor(String): void
}
class Circle {
- radius: double
+ calculateArea(): double
}
class Rectangle {
- width: double
- height: double
+ calculateArea(): double
}
interface Drawable {
+ draw(): void
}
Shape <|-- Circle
Shape <|-- Rectangle
Drawable <|.. Circle
Drawable <|.. Rectangle
note right of Shape
Abstract class
(shown in italics)
Cannot be instantiated
end note
note right of Drawable
Interface
(dashed line for implementation)
end note
@enduml

Association: A class A is associated with class B if class A contains some reference to class B anywhere inside the class (as a field, method parameter, or return type).

A weak association where an object accepts another object as a method parameter or return type.

Example:

Driver.java
// Dependency: Vehicle is only used as a method parameter
public class Driver {
public void drive(Vehicle vehicle) {
vehicle.accelerate();
}
}
public class Vehicle {
public void accelerate() {
// Implementation
}
}

A Has-A relationship where the container holds a reference to the contained object. The contained object can exist independently and may be used by other parts of the system.

Example:

Car.java (Aggregation)
public class Car {
// Car Has-A Engine (reference only)
private Engine engine;
// Engine created separately and passed in
public Car(Engine engine) {
this.engine = engine;
}
public void start() {
engine.start();
}
}
public class Engine {
private int horsePower;
public Engine(int horsePower) {
this.horsePower = horsePower;
}
public void start() {
System.out.println("Engine started");
}
}

Also a Has-A relationship, but with strong coupling. The container directly owns the contained object. If the container dies, the contained object ceases to exist.

Example:

Vehicle.java (Composition)
public class Vehicle {
private Engine myEngine; // Vehicle owns Engine
// Engine created inside constructor (composition)
public Vehicle(int horsePower) {
myEngine = new Engine(horsePower); // Created here!
}
public void start() {
myEngine.start();
}
}

Another Example:

ParkingFloor.java (Strong Ownership)
public class ParkingFloor {
// HashMap directly owns all ParkingSpot instances
private Map<String, ParkingSpot> spots;
public ParkingFloor(int capacity) {
spots = new HashMap<>();
// Create parking spots (composition)
for (int i = 0; i < capacity; i++) {
String spotId = "S" + i;
spots.put(spotId, new ParkingSpot(spotId));
}
}
}

If ParkingFloor is removed, all ParkingSpot instances are automatically removed.


Examples:

[Vehicle] ----> [Engine] (Vehicle depends on Engine)
[College] ----> [Branches] (College depends on Branches)
[College] ----> [Professor] (College depends on Professor)

The arrow shows the direction of knowledge and communication flow.


Dependency → Association → Aggregation → Composition

RelationshipSymbolStrengthExample
DependencyA ..> BWeakestDriver (A) uses Vehicle (B)
AssociationA --> BWeakAdmin (A) → ParkingFloor (B)
AggregationA o-- BModeratePerson (A) Has-A Address (B)
CompositionA *-- BStrongestParkingFloor (A) owns Spots (B)
InheritanceA <|-- B-Dog (B) IS-A Animal (A)

Error generating PlantUML diagram: connect ECONNREFUSED 127.0.0.1:8080

@startuml
skinparam backgroundColor #ffffff
skinparam Shadowing false
skinparam DefaultFontName Arial
skinparam DefaultFontSize 11
skinparam ArrowColor #475569
skinparam classBackgroundColor #f8fafc
skinparam classBorderColor #64748b
class Driver
class Vehicle
Driver ..> Vehicle : "Dependency"
class Admin
class ParkingFloor
Admin --> ParkingFloor : "Association"
class Person
class Address
Person o-- Address : "Aggregation"
class ParkingFloor2 as "ParkingFloor"
class ParkingSpot
ParkingFloor2 *-- ParkingSpot : "Composition"
class Animal
class Dog
Animal <|-- Dog : "Inheritance"
@enduml