#include <iostream>
#include <memory>

// ---------- Split interfaces that follow ISP ----------
// Interface that contains only printing functionality
class IPrintable {
public:
    virtual ~IPrintable() = default;
    virtual void print() = 0;
};

// Interface that contains only scanning functionality
class IScannable {
public:
    virtual ~IScannable() = default;
    virtual void scan() = 0;
};

// ---------- Concrete implementation classes, implemented on demand ----------
// Simple printer: only needs to implement IPrintable
class SimplePrinter : public IPrintable {
public:
    void print() override {
        std::cout << "[SimplePrinter] Printing a document..." << std::endl;
    }
};

// Simple scanner: only needs to implement IScannable
class SimpleScanner : public IScannable {
public:
    void scan() override {
        std::cout << "[SimpleScanner] Scanning a document..." << std::endl;
    }
};

// Multifunction device: supports both printing and scanning, so it implements both interfaces
class MultiFunctionMachine : public IPrintable, public IScannable {
private:
    // You can compose concrete components, or implement the functionality directly here
public:
    void print() override {
        std::cout << "[MultiFunctionMachine] Printing..." << std::endl;
    }

    void scan() override {
        std::cout << "[MultiFunctionMachine] Scanning..." << std::endl;
    }
};

// ---------- Client code ----------
// Function that depends only on the IPrintable interface
void performPrint(IPrintable& printer) {
    printer.print();
}

// Function that depends only on the IScannable interface
void performScan(IScannable& scanner) {
    scanner.scan();
}

int main() {
    // Create concrete objects
    SimplePrinter printer;
    SimpleScanner scanner;
    MultiFunctionMachine mfp;

    std::cout << "===== Example of the Interface Segregation Principle =====" << std::endl;

    // Printer uses only the printing feature
    std::cout << "\n--- Using the printer ---" << std::endl;
    performPrint(printer);

    // Scanner uses only the scanning feature
    std::cout << "\n--- Using the scanner ---" << std::endl;
    performScan(scanner);

    // A multifunction device can use both
    std::cout << "\n--- Using the multifunction device ---" << std::endl;
    performPrint(mfp);
    performScan(mfp);

    // Demonstrate an unimplemented feature — because of interface segregation, SimplePrinter does not need to provide scan()
    // The following code will fail to compile (uncomment to see it):
    // performScan(printer); // Error: SimplePrinter is not a subclass of IScannable

    std::cout << "\nThe Interface Segregation Principle is followed: "
              << "SimplePrinter and SimpleScanner are not forced to implement methods they do not need.\n";

    return 0;
}

results matching ""

    No results matching ""