Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between Factory method design pattern and Bridge pattern?

Hello All,

Could someone please explain me the difference between Factory method design pattern and Bridge pattern?

Because from my understanding, both these design patterns are using to separate interface and implementation:

Decoupling abstraction from implementation. Abstraction separates the client code from the implementation. So, the implementation can be changed without affecting the client code and the client code need not be compiled when the implementation changes.

Factory Method:

Problem without Factory method:

There are cases where we have a library with some classes to implement the client business logic. From the client application we create objects of the library classes to complete the task.

But sometimes, based on the client requirement to incorporate additional functionality, we might need to add additional classes in the library. Then we need to create objects of the new classes in the client application.

So, each time a new change is made at the library side, Client would need to make some corresponding changes at its end and recompile the code.

Using Factory Method:

To avoid this problem, we decouple object creation from client application using Factory method. Client just needs to make call to library’s factory method without worrying about the actual implementation of creation of objects.

So we create Factory method to create objects and move it to the separate implementation file. Now the implementation file is the only one that requires knowledge of the derived classes. Thus, if a change is made to any derived class, or any new class is added, the implementation file is the only file that needs to be recompiled. Everyone who uses the factory will only care about the interface, which should remain consistent throughout the life of the application.

Client Application interacts -> Factory method and calls--> Implementation

If I take the below sample program, after adding any class or any change in the class is it enough to recompile only Vehicle.cpp file? And also when creating factory method, do we use static method?

Vehicle.h

#include <iostream> 
using namespace std; 

enum VehicleType { 
    VT_TwoWheeler,    VT_ThreeWheeler,    VT_FourWheeler 
}; 

// Library classes 
class Vehicle { 
public: 
    virtual void printVehicle() = 0; 
    static Vehicle* Create(VehicleType type); 
}; 
class TwoWheeler : public Vehicle { 
public: 
    void printVehicle() { 
        cout << "I am two wheeler" << endl; 
    } 
}; 
class ThreeWheeler : public Vehicle { 
public: 
    void printVehicle() { 
        cout << "I am three wheeler" << endl; 
    } 
}; 
class FourWheeler : public Vehicle { 
    public: 
    void printVehicle() { 
        cout << "I am four wheeler" << endl; 
    } 
}; 

Vehicle.cpp (Implementation file)

// Factory method to create objects of different types. 
// Change is required only in this function to create a new object type 
Vehicle* Vehicle::Create(VehicleType type) { 
    if (type == VT_TwoWheeler) 
        return new TwoWheeler(); 
    else if (type == VT_ThreeWheeler) 
        return new ThreeWheeler(); 
    else if (type == VT_FourWheeler) 
        return new FourWheeler(); 
    else return NULL; 
} 

Client.h file

// Client class 
class Client { 
public: 

    // Client doesn't explicitly create objects 
    // but passes type to factory method "Create()" 
    Client() 
    { 
        VehicleType type = VT_ThreeWheeler; 
        pVehicle = Vehicle::Create(type); 
    } 
    ~Client() { 
        if (pVehicle) { 
            delete[] pVehicle; 
            pVehicle = NULL; 
        } 
    } 
    Vehicle* getVehicle()  { 
        return pVehicle; 
    } 

private: 
    Vehicle *pVehicle; 
}; 

// Driver program 

int main() { 
    Client *pClient = new Client(); 
    Vehicle * pVehicle = pClient->getVehicle(); 
    pVehicle->printVehicle(); 
    return 0; 
}

Please provide your thoughts on this.

Thanks in advance.

like image 849
John Paul Coder Avatar asked Nov 07 '22 15:11

John Paul Coder


1 Answers

Factory Method is about flexibility of creating objects with provision to create new objects, unknown at the time of creating base code. For example, lets say you are designing interface wrapper for IO cards to be integrated with your project. You start with Decklink card and Bluefish card. Later you want to add Matrox card without modifying any of the past codes, Factory pattern will come to your rescue.

Bridge Pattern is more about delinking interface from implementation ( hide the complicated code).

Ceveat in your code: Say you want to add VT_FiveWheeler - you have to modify Vehicle.h to add in enum VehicleType (sounds bad). Create Method can be static or it can be a simple helper function like so:

namespace Vehicle {
    class Vehicle {
    public:
        virtual void printVehicle() = 0;
    };
}

namespace Vehicle {
    namespace TwoWheeler {

        class TwoWheeler : public Vehicle {
        public:
            void printVehicle() {
                cout << "I am two wheeler" << endl;
            }
        };
        shared_ptr<Vehicle> create() { return make_shared<TwoWheeler>(); }
    }
}

namespace Vehicle {
    namespace ThreeWheeler {
        class ThreeWheeler : public Vehicle {
        public:
            void printVehicle() {
                cout << "I am three wheeler" << endl;
            }
        };
        shared_ptr<Vehicle> create() { return make_shared<ThreeWheeler>(); }
    }
}

namespace Vehicle {
    class factory
    {
        typedef function<shared_ptr<Vehicle>(void) > func_t;

    public:

        //register a vehicle
        void register_vehicle(const string& name, func_t func)
        {
            registered_vehicles_.insert(make_pair(name, func));
        }

        //to create a vehicle
        shared_ptr<Vehicle> create_vehicle(string name)
        {
            return registered_vehicles_[name]();
        }

        map<string, func_t> get() { return registered_vehicles_;  }

    private:
        map<string, func_t> registered_vehicles_;
    };
}

Vehicle::factory my_vehicle_factory;


int main() {

    //register the vehicle in the factory first
    my_vehicle_factory.register_vehicle("TwoWheeler", Vehicle::TwoWheeler::create);

    auto p1 = my_vehicle_factory.create_vehicle("TwoWheeler");
    auto p2 = my_vehicle_factory.create_vehicle("TwoWheeler");

    // A new vehicle has arrived, so first registered it
    my_vehicle_factory.register_vehicle("ThreeWheeler", Vehicle::ThreeWheeler::create);
    auto p3 = my_vehicle_factory.create_vehicle("ThreeWheeler");


    p1->printVehicle();
    p2->printVehicle();
    p3->printVehicle();
}
like image 177
seccpur Avatar answered Nov 09 '22 23:11

seccpur