Right design pattern to deal with polymorphic collections of objects

后端 未结 5 1050
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-22 04:59

Suppose I have the following classes:

class BaseObject {
    public:
        virtual int getSomeCommonProperty();
};

class Object1: public BaseObject {
    publ         


        
5条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-22 05:36

    I think the solution should be a mix of factory method pattern and template method pattern. Take a look at those to refine your design.

    Edit: Here is a sample code. GenericProduct is the BaseObject, it provides two methods, one that is general (though it could be overridden), and a specific method which does nothing, it is not a pure virtual so this class can be instantiated. SpecificProduct is a subclass, which implements the specific method in some way.

    Now, Factory class is an abstract class that defines an interface for creating specific products by specific factories, it defines a pure virtual method createProduct which creates the product. Two concrete factories are created GenericFactory and SpecificFactory which create specific products.

    Finally, the Consumer abstract class (which corresponds to BaseCollection in your code), it defines a pure virtual method for creating a factory createFactory in order to force subclasses to create their own concrete factories (and hence, the correct products). The class also define a method fillArray (prototype pattern) to fill the array with products created by the factory.

    #include 
    #include 
    
    using namespace std;
    
    class GenericProduct{
        public:
            virtual void getSomeCommonProperty()
            {
                cout<<"Common Property\n";
            }
            virtual void getSomeSpecificProperty()
            {
                cout<<"Generic Has Nothing Specific\n";
            }
    };
    
    class SpecificProduct : public GenericProduct{
        public:
            virtual void getSomeSpecificProperty()
            {
                cout<<"Specific Product Has a Specific Property\n";
            }
    };
    
    class Factory
    {
        public:
            virtual GenericProduct* createProduct() = 0;
    };
    
    class GenericFactory : public Factory
    {
        public:
            virtual GenericProduct* createProduct()
            {
                return new GenericProduct();
            }
    };
    
    class SpecificFactory : public Factory
    {
        public:
            virtual GenericProduct* createProduct()
            {
                return new SpecificProduct();
            }
    };
    
    class Consumer
    {
        protected:
            vector gp;
            Factory* factory;
    
        protected:
            virtual void createFactory() = 0;
    
        public: 
            void fillArray()
            {
                createFactory();
                for(int i=0; i<10; i++)
                {
                    gp.push_back(factory->createProduct());
                }
            }
    
            virtual void someCommonTask()
            {
                cout<<"Performaing a Common Task ...\n";
                for(int i=0; i<10; i++)
                {
                    gp[i]->getSomeCommonProperty();
                }
            }
            virtual void someSpecificTask()
            {
                cout<<"Performaing a Specific Task ...\n";
                for(int i=0; i<10; i++)
                {
                    gp[i]->getSomeSpecificProperty();
                }
            }
    };
    
    class GenericConsumer : public Consumer
    {
        virtual void createFactory()
        {
            factory = new GenericFactory();
        }
    };
    
    class SpecificConsumer : public Consumer
    {
        virtual void createFactory()
        {
            factory = new SpecificFactory();
        }
    };
    
    
    int main()
    {
        Consumer* c = new GenericConsumer();
        c->fillArray();
        c->someCommonTask();
        return 0;
    }
    

提交回复
热议问题