0

So I have a requirement for something like this:

  • The client shouldn't be aware of how the actual classes are implemented or constructed.

  • The classes implement a common interface

So I used Factory class to cater to 1 and an abstract class to implement the second point.

Hence I came up with something like this (a simplification of my class design):

#include <iostream>
#include <cstddef>

enum variety{
    oolong,
    green,
};

class T
{
    public:
        virtual void drink() = 0;
        virtual ~T() {};
};

class T1: public T
{
    T1() = delete;
    public:
        T1(int a):
          sugar(a)
          {
              std::cout<<"T1 ctor\n";
          }
        void drink()
        {
            std::cout<<"Sipping oolong with sugar: "<<sugar<<'\n';
        }
        ~T1()
        {
            std::cout<<"T1 dtor\n";
        }
    private:
        int sugar;
};

class T2: public T
{
    T2() = delete;
    public:
        T2(int a):
          sugar(a)
          {
              std::cout<<"T2 ctor\n";
          }
        void drink()
        {
            std::cout<<"Sipping green with sugar: "<<sugar<<'\n';
        }
        ~T2()
        {
            std::cout<<"T2 dtor\n";
        }
    private:
        int sugar;
};

class TFactory
{
    TFactory() = delete;
    public:
        static T* brew(variety v, int sugar){
            if(v == oolong)
                return new T1(sugar);
            else if (v== green)
                return new T2(sugar);
            else
                return nullptr;
        }
};

int main(){
    T* t1 = TFactory::brew(oolong, 5);
    t1->drink();
    delete t1;
}

Is this the best approach to designing my requirement? Or is there some other existing design pattern that already covers my requirement? If so, what are the lacunae in my code that makes it a bad design?

  • Only thing that really pops out to me is returning raw pointers to memory that needs to be explicitly freed from the factory. Any kind of exception thrown between that and the client calling operator delete would leak. I'd favor returning a unique_ptr in that case with move semantics. – Dragon Energy Dec 14 '18 at 14:31
1

I guess the core of your application is using the abstract class T as well as the TFactory.

In this case you want to decouple the non volatile core from frequent changes in the subtypes of T. But you would be directly depending on the TFactory which violates the dependency inversion principle / open closed principle. The result is that every time you add or change a subtype of T the code that uses the Factory is affected through the change and at least needs to be recompiled.

To solve this issue you could place your TFactory behind an additional interface (Abstract Factory) to decouple the codes.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.