muhammadbadrul1234 / ElDorado-Travel-and-Tour-Management-System

The main purpose of this system is to provide a efficient way for a customer to book hotels, flight, train and bus. Also it automates the processes and activities of a travel agency.
MIT License
16 stars 5 forks source link

Bad Coding Smells concerns: Long Method #34

Open Jazarumag opened 10 months ago

Jazarumag commented 10 months ago

THIS ISSUE IS POSTED AS A COLLEGE ASSIGNMENT ON BAD CODING SMELLS AND REFACTORING TECHNIQUES, PLEASE CLOSE THIS ISSUE IF IT'S OF NO USE.

I found some bad smells in your coding, so i tried to fix them by refactoring some parts of it.

To refactor the method busdestination() in the class Transportation.java, remove the "long method" and apply "Extract method" and "Enter Parameter Object" to refactor.

Extract Method: Split the method into several smaller methods with descriptive names. This improves the readability and maintainability of the code.

void busdestination() {
    Scanner scan = new Scanner(System.in);
    String destination;
    String to;
    System.out.print("\t\t\t\t\t\t Enter Start Point:");
    to = scan.nextLine();
    System.out.print("\t\t\t\t\t\t Enter Destination:");
    destination = scan.nextLine();

    new UserInterface().loadingBar();
    clearScreenAndDisplayLogo();
    showAvailableBuses(destination);
    int num1 = getBusSelection(scan);
    int num2 = getTicketQuantity(scan);
    processOrder(to, destination, num1, num2);
}

private void clearScreenAndDisplayLogo() {
    System.out.print("\033[H\033[2J");
    logo.logo();
}

private void showAvailableBuses(String destination) {
    System.out.println("\t\t\t\t\t\tThe Available Buses list According to Your Destination:  ");
    System.out.print(
            "\t\t\t\t_________________________________________________________________________________________\n");
    System.out.print(
            "\t\t\t\t|   SL  |         Route         |           Bus Name    |  Time | Fare  |AvailableTicket|");
    System.out.print(
            "\n\t\t\t\t+---------------------------------------------------------------------------------------+");
    displayBusDetails(destination);
    System.out.print(
            "\n\t\t\t\t+---------------------------------------------------------------------------------------+\n");
}

private void displayBusDetails(String destination) {
    ArrayList<Integer> Fares = new MongoDB().mongoDBBusFinder(to, destination);
    // display bus details using Fares
}

private int getBusSelection(Scanner scan) {
    System.out.print("\t\t\t\t Which one do you want to buy       : ");
    return scan.nextInt();
}

private int getTicketQuantity(Scanner scan) {
    System.out.print("\t\t\t\t How many Tickets do you want to buy: ");
    return scan.nextInt();
}

private void processOrder(String to, String destination, int num1, int num2) {
    ArrayList<Integer> Fares = new MongoDB().mongoDBBusFinder(to, destination);
    int cost = Fares.get(num1 - 1) * num2;
    displayOrderConfirmation(cost);
}

private void displayOrderConfirmation(int cost) {
    System.out.print(
            "\n\t\t\t\t_________________________________________________________________________________________");
    System.out.print(
            "\n\t\t\t\t|                             Order Taken Successfully                                  |");
    System.out.print(
            "\n\t\t\t\t|   Please Press Enter Key to Confirm your Purchase. Your bank Account will be Charged  |");
    System.out.print(
            "\n\t\t\t\t|_______________________________________________________________________________________|\n");
    new UserInterface().promptEnterKey();

    System.out.print("\t\t\t\t " + cost);
}

Enter Parameter Object: Group the related parameters into an object and pass it as a single parameter to the method.

class BusOrder {
    String startLocation;
    String destination;
    int busSelection;
    int ticketQuantity;

    // Constructor, getters, and setters
}

void busdestination() {
    Scanner scan = new Scanner(System.in);
    BusOrder busOrder = getBusOrder(scan);

    new UserInterface().loadingBar();
    clearScreenAndDisplayLogo();
    showAvailableBuses(busOrder.getDestination());
    processOrder(busOrder);
}

private BusOrder getBusOrder(Scanner scan) {
    BusOrder busOrder = new BusOrder();
    System.out.print("\t\t\t\t\t\t Enter Start Point:");
    busOrder.setStartLocation(scan.nextLine());
    System.out.print("\t\t\t\t\t\t Enter Destination:");
    busOrder.setDestination(scan.nextLine());

    busOrder.setBusSelection(getBusSelection(scan));
    busOrder.setTicketQuantity(getTicketQuantity(scan));

    return busOrder;
}

private void processOrder(BusOrder busOrder) {
    ArrayList<Integer> Fares = new MongoDB().mongoDBBusFinder(busOrder.getStartLocation(), busOrder.getDestination());
    int cost = Fares.get(busOrder.getBusSelection() - 1) * busOrder.getTicketQuantity();
    displayOrderConfirmation(cost);
}

Also the conditionals you are using are hard to understand, you coul "Decompose Conditional" as a possible solution.

void busdestination() {
    Scanner scan = new Scanner(System.in);
    BusOrder busOrder = getBusOrder(scan);

    new UserInterface().loadingBar();
    clearScreenAndDisplayLogo();
    showAvailableBuses(busOrder.getDestination());

    if (confirmOrder(scan)) {
        processOrder(busOrder);
    }
}

private boolean confirmOrder(Scanner scan) {
    System.out.print("\t\t\t\t Do you want to confirm your purchase? (Y/N): ");
    String confirmation = scan.next().toUpperCase();
    return confirmation.equals("Y");
}

// Rest of the methods remain the same...