cppadvanced15 minutes

Refactor Complex C++ Class for Improved Readability and Maintainability

Given a complex and messy C++ class implementation, refactor the code to improve readability, maintainability, and follow best OOP practices without changing the program's behavior.

Challenge prompt

You are provided with a C++ class that manages an inventory of items. The implementation works correctly but is cluttered with deeply nested conditionals, duplicated code, and poor separation of concerns. Refactor the class to improve clarity, structure, and code quality while keeping all existing functionality intact. Avoid changing method signatures and external behavior. Your refactor should focus on reducing code duplication, improving naming, simplifying complex logic, and enhancing code modularity.

Guidance

  • Identify and extract repeated code snippets into helper functions or private methods.
  • Replace deeply nested if-else blocks with early returns or guard clauses to simplify flow.
  • Review variable and method names, improving clarity and intent.
  • Consider applying design principles such as Single Responsibility Principle to enhance modularity.

Hints

  • Look for patterns where several branches execute similar code with slight variations; these can be unified.
  • Extracting small functions not only improves readability but also helps isolate logical units for testing.
  • Try replacing boolean flags and counters that track states across methods with well-defined state representations.

Starter code

#include <iostream>
#include <vector>
#include <string>

class Inventory {
public:
    Inventory() {}

    void addItem(std::string name, int quantity) {
        if (quantity > 0) {
            int index = -1;
            for (int i = 0; i < items.size(); ++i) {
                if (items[i] == name) {
                    index = i;
                    break;
                }
            }
            if (index == -1) {
                items.push_back(name);
                quantities.push_back(quantity);
            } else {
                quantities[index] += quantity;
            }
        } else {
            std::cout << "Invalid quantity\n";
        }
    }

    void removeItem(std::string name, int quantity) {
        if (quantity <= 0) {
            std::cout << "Cannot remove non-positive quantity\n";
            return;
        }
        for (int i = 0; i < items.size(); ++i) {
            if (items[i] == name) {
                if (quantities[i] < quantity) {
                    std::cout << "Not enough quantity to remove\n";
                } else {
                    quantities[i] -= quantity;
                    if (quantities[i] == 0) {
                        items.erase(items.begin() + i);
                        quantities.erase(quantities.begin() + i);
                    }
                }
                return;
            }
        }
        std::cout << "Item not found" << std::endl;
    }

    void printInventory() {
        if (items.size() == 0) {
            std::cout << "Inventory is empty" << std::endl;
        } else {
            for (size_t i = 0; i < items.size(); ++i) {
                std::cout << items[i] << ": " << quantities[i] << std::endl;
            }
        }
    }

private:
    std::vector<std::string> items;
    std::vector<int> quantities;
};

int main() {
    Inventory inv;
    inv.addItem("apple", 10);
    inv.addItem("banana", 5);
    inv.removeItem("apple", 3);
    inv.printInventory();
    inv.removeItem("banana", 6);
    inv.printInventory();
    return 0;
}

Expected output

apple: 7 banana: 5 Not enough quantity to remove apple: 7 banana: 5

Core concepts

Code RefactoringC++ Best PracticesObject-Oriented ProgrammingCode Maintenance

Challenge a Friend

Send this duel to someone else and see if they can solve it.