Design pattern to be used in Airline Management System
An Airline Management System leverages various design patterns to ensure scalability, maintainability, and efficiency
1. Singleton Pattern
Description:
The Singleton Pattern ensures that a class has only one instance throughout the application lifecycle. It provides a global point of access to that instance. This is commonly used for managing shared resources such as configuration settings, logging, or database connections.
Use Case in Airline Management System:
A ConfigurationManager
can hold system-wide settings (e.g., database credentials, API keys) that need to be accessed consistently across various parts of the system.
Code Example:
public class ConfigurationManager {
private static ConfigurationManager instance;
private ConfigurationManager() {
// Private constructor to prevent instantiation
}
public static ConfigurationManager getInstance() {
if (instance == null) {
synchronized (ConfigurationManager.class) { // Thread-safe initialization
if (instance == null) {
instance = new ConfigurationManager();
}
}
}
return instance;
}
public String getConfiguration(String key) {
// Fetch configuration by key
return "Value for " + key;
}
}
2. Factory Pattern
Description:
The Factory Pattern provides an interface for creating objects in a superclass but allows subclasses to alter the type of objects that will be created. This is useful when you need to create objects dynamically based on input or type.
Use Case in Airline Management System:
Creating ticket types dynamically, such as Economy, Business, or First-Class tickets.
Code Example:
abstract class Ticket {
abstract void ticketDetails();
}
class EconomyTicket extends Ticket {
@Override
void ticketDetails() {
System.out.println("Economy Ticket");
}
}
class BusinessTicket extends Ticket {
@Override
void ticketDetails() {
System.out.println("Business Ticket");
}
}
class TicketFactory {
public static Ticket getTicket(String type) {
if (type.equalsIgnoreCase("Economy")) {
return new EconomyTicket();
} else if (type.equalsIgnoreCase("Business")) {
return new BusinessTicket();
}
return null;
}
}
3. Builder Pattern
Description:
The Builder Pattern is used to construct a complex object step by step. It provides greater control over the construction process and is ideal for creating immutable objects with optional parameters.
Use Case in Airline Management System:
Building complex itineraries for passengers, with optional fields like meal preferences, seat selection, and baggage options.
Code Example:
class Itinerary {
private String passengerName;
private String flightNumber;
private String seatNumber;
private Itinerary(ItineraryBuilder builder) {
this.passengerName = builder.passengerName;
this.flightNumber = builder.flightNumber;
this.seatNumber = builder.seatNumber;
}
@Override
public String toString() {
return "Itinerary [Passenger=" + passengerName + ", Flight=" + flightNumber + ", Seat=" + seatNumber + "]";
}
public static class ItineraryBuilder {
private String passengerName;
private String flightNumber;
private String seatNumber;
public ItineraryBuilder setPassengerName(String passengerName) {
this.passengerName = passengerName;
return this;
}
public ItineraryBuilder setFlightNumber(String flightNumber) {
this.flightNumber = flightNumber;
return this;
}
public ItineraryBuilder setSeatNumber(String seatNumber) {
this.seatNumber = seatNumber;
return this;
}
public Itinerary build() {
return new Itinerary(this);
}
}
}
Itinerary itinerary = new Itinerary.ItineraryBuilder()
.setPassengerName("John Doe")
.setFlightNumber("AI123")
.setSeatNumber("12A")
.build();
System.out.println(itinerary);
4. Strategy Pattern
Description:
The Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It allows you to change the behavior of an object at runtime.
Use Case in Airline Management System:
Different pricing strategies for tickets (e.g., regular pricing, discount pricing).
Code Example:
interface PricingStrategy {
double calculatePrice(double basePrice);
}
class RegularPricing implements PricingStrategy {
@Override
public double calculatePrice(double basePrice) {
return basePrice;
}
}
class DiscountPricing implements PricingStrategy {
@Override
public double calculatePrice(double basePrice) {
return basePrice * 0.9; // 10% discount
}
}
class TicketPrice {
private PricingStrategy strategy;
public TicketPrice(PricingStrategy strategy) {
this.strategy = strategy;
}
public double getFinalPrice(double basePrice) {
return strategy.calculatePrice(basePrice);
}
}
TicketPrice regularPrice = new TicketPrice(new RegularPricing());
System.out.println("Regular Price: " + regularPrice.getFinalPrice(1000));
TicketPrice discountPrice = new TicketPrice(new DiscountPricing());
System.out.println("Discounted Price: " + discountPrice.getFinalPrice(1000));
5. Observer Pattern
Description:
The Observer Pattern allows one object (subject) to notify a group of dependent objects (observers) of state changes.
Use Case in Airline Management System:
Notifying passengers of flight delays or cancellations.
Code Example:
import java.util.ArrayList;
import java.util.List;
interface Observer {
void update(String message);
}
class Passenger implements Observer {
private String name;
public Passenger(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received update: " + message);
}
}
class Flight {
private List<Observer> passengers = new ArrayList<>();
public void addPassenger(Observer passenger) {
passengers.add(passenger);
}
public void notifyPassengers(String message) {
for (Observer passenger : passengers) {
passenger.update(message);
}
}
}
6. Decorator Pattern
Description:
The Decorator Pattern dynamically adds behavior or responsibilities to objects without modifying their code.
Use Case in Airline Management System:
Adding extra services (e.g., meals, extra baggage) to tickets.
Code Example:
interface TicketService {
String getDescription();
double getCost();
}
class BasicTicket implements TicketService {
@Override
public String getDescription() {
return "Basic Ticket";
}
@Override
public double getCost() {
return 500.0;
}
}
class MealAddon extends BasicTicket {
private TicketService ticket;
public MealAddon(TicketService ticket) {
this.ticket = ticket;
}
@Override
public String getDescription() {
return ticket.getDescription() + " + Meal";
}
@Override
public double getCost() {
return ticket.getCost() + 100.0;
}
}