(Polymorphism) Addition parameter pass to constructor of derived class in factory pattern












0















In factory pattern, we use a Factory class to produce a Product class that implement Abstract Product.



interface AbstractProduct {
public string getDetail();
}

class Product_A : AbstractProduct {
public string getDetail();
}

class Product_B : AbstractProduct {
public string getDetail();
}

class Factory {
public AbstractProduct produce(int product_id){
if (product_id == 1){
return Product_A();
}
else if (product_id == 2){
return Product_B();
}
}
}

int main() {
Factory factory = new Factory();
int id; // a random number either 1 or 2

print(factory.produce(id).getDetail());
}


My question is, what if today we need extract information to pass into Product_B from main(), for example a reference of a class instance.



int main() {
// object that need to be passed into Product_B
Database database = new Database();

Factory factory = new Factory();
int id; // a random number either 1 or 2

print(factory.produce(id).getDetail());
}

class Product_B : AbstractProduct {
public string getDetail() {
// I need the reference of database here.
// I'm unable to instance a database in side Product_B.
// I need to somehow pass it into Product_B.
database.query();
}
}


The only solution come to my mind is...



class Factory {
// pass the reference here
public AbstractProduct produce(int product_id, Database db){
if (product_id == 1){
return Product_A();
}
else if (product_id == 2){
return Product_B(db);
}
}
}


Is there any good solution or relative design pattern can solve this problem Elegant and Clean ? Thanks a lot.










share|improve this question























  • Instead of passing a product_id to your 'produce' method, you could pass an object that is polymorphic. Let's say the base class of that object only contains the product_id, but then you could subclass it and potentially add parameters to it based on your use-case.

    – AlexG
    Nov 19 '18 at 17:39













  • @AlexG, thanks for your comment. But what is the different between this method and pass (product_id, db). Because the Factory return Product mostly base on product_id, and sometime it need additional information, say db, and I don't know when will it be required. So how can I determine whether to pass BaseClass with product_id or DeriveClass with (product_id, db)?

    – 王予智
    Nov 19 '18 at 17:53











  • I have no idea of your use-case, but it feels like if you need to add parameters or do a bunch of conditional stuff, then the factory pattern isn't the right choice. My approach was to provide a single function signature and be able to pass in different parameters, which implies the caller knows a few things about what will be instantiated.

    – AlexG
    Nov 19 '18 at 18:30











  • My detail use-case is that I'm working MVC web page where I need to process data from a row of database column (e.x. GET ? product_id=1). Because I need to use different strategy to process the data base on product_id, so I pass product_id to a Factory and get relevant class to process it. However, during some special product, I need to query more data from database, so I need the reference of $this->db from Codeigniter controller to pass to the derive object that produce by Factory

    – 王予智
    Nov 19 '18 at 18:44
















0















In factory pattern, we use a Factory class to produce a Product class that implement Abstract Product.



interface AbstractProduct {
public string getDetail();
}

class Product_A : AbstractProduct {
public string getDetail();
}

class Product_B : AbstractProduct {
public string getDetail();
}

class Factory {
public AbstractProduct produce(int product_id){
if (product_id == 1){
return Product_A();
}
else if (product_id == 2){
return Product_B();
}
}
}

int main() {
Factory factory = new Factory();
int id; // a random number either 1 or 2

print(factory.produce(id).getDetail());
}


My question is, what if today we need extract information to pass into Product_B from main(), for example a reference of a class instance.



int main() {
// object that need to be passed into Product_B
Database database = new Database();

Factory factory = new Factory();
int id; // a random number either 1 or 2

print(factory.produce(id).getDetail());
}

class Product_B : AbstractProduct {
public string getDetail() {
// I need the reference of database here.
// I'm unable to instance a database in side Product_B.
// I need to somehow pass it into Product_B.
database.query();
}
}


The only solution come to my mind is...



class Factory {
// pass the reference here
public AbstractProduct produce(int product_id, Database db){
if (product_id == 1){
return Product_A();
}
else if (product_id == 2){
return Product_B(db);
}
}
}


Is there any good solution or relative design pattern can solve this problem Elegant and Clean ? Thanks a lot.










share|improve this question























  • Instead of passing a product_id to your 'produce' method, you could pass an object that is polymorphic. Let's say the base class of that object only contains the product_id, but then you could subclass it and potentially add parameters to it based on your use-case.

    – AlexG
    Nov 19 '18 at 17:39













  • @AlexG, thanks for your comment. But what is the different between this method and pass (product_id, db). Because the Factory return Product mostly base on product_id, and sometime it need additional information, say db, and I don't know when will it be required. So how can I determine whether to pass BaseClass with product_id or DeriveClass with (product_id, db)?

    – 王予智
    Nov 19 '18 at 17:53











  • I have no idea of your use-case, but it feels like if you need to add parameters or do a bunch of conditional stuff, then the factory pattern isn't the right choice. My approach was to provide a single function signature and be able to pass in different parameters, which implies the caller knows a few things about what will be instantiated.

    – AlexG
    Nov 19 '18 at 18:30











  • My detail use-case is that I'm working MVC web page where I need to process data from a row of database column (e.x. GET ? product_id=1). Because I need to use different strategy to process the data base on product_id, so I pass product_id to a Factory and get relevant class to process it. However, during some special product, I need to query more data from database, so I need the reference of $this->db from Codeigniter controller to pass to the derive object that produce by Factory

    – 王予智
    Nov 19 '18 at 18:44














0












0








0








In factory pattern, we use a Factory class to produce a Product class that implement Abstract Product.



interface AbstractProduct {
public string getDetail();
}

class Product_A : AbstractProduct {
public string getDetail();
}

class Product_B : AbstractProduct {
public string getDetail();
}

class Factory {
public AbstractProduct produce(int product_id){
if (product_id == 1){
return Product_A();
}
else if (product_id == 2){
return Product_B();
}
}
}

int main() {
Factory factory = new Factory();
int id; // a random number either 1 or 2

print(factory.produce(id).getDetail());
}


My question is, what if today we need extract information to pass into Product_B from main(), for example a reference of a class instance.



int main() {
// object that need to be passed into Product_B
Database database = new Database();

Factory factory = new Factory();
int id; // a random number either 1 or 2

print(factory.produce(id).getDetail());
}

class Product_B : AbstractProduct {
public string getDetail() {
// I need the reference of database here.
// I'm unable to instance a database in side Product_B.
// I need to somehow pass it into Product_B.
database.query();
}
}


The only solution come to my mind is...



class Factory {
// pass the reference here
public AbstractProduct produce(int product_id, Database db){
if (product_id == 1){
return Product_A();
}
else if (product_id == 2){
return Product_B(db);
}
}
}


Is there any good solution or relative design pattern can solve this problem Elegant and Clean ? Thanks a lot.










share|improve this question














In factory pattern, we use a Factory class to produce a Product class that implement Abstract Product.



interface AbstractProduct {
public string getDetail();
}

class Product_A : AbstractProduct {
public string getDetail();
}

class Product_B : AbstractProduct {
public string getDetail();
}

class Factory {
public AbstractProduct produce(int product_id){
if (product_id == 1){
return Product_A();
}
else if (product_id == 2){
return Product_B();
}
}
}

int main() {
Factory factory = new Factory();
int id; // a random number either 1 or 2

print(factory.produce(id).getDetail());
}


My question is, what if today we need extract information to pass into Product_B from main(), for example a reference of a class instance.



int main() {
// object that need to be passed into Product_B
Database database = new Database();

Factory factory = new Factory();
int id; // a random number either 1 or 2

print(factory.produce(id).getDetail());
}

class Product_B : AbstractProduct {
public string getDetail() {
// I need the reference of database here.
// I'm unable to instance a database in side Product_B.
// I need to somehow pass it into Product_B.
database.query();
}
}


The only solution come to my mind is...



class Factory {
// pass the reference here
public AbstractProduct produce(int product_id, Database db){
if (product_id == 1){
return Product_A();
}
else if (product_id == 2){
return Product_B(db);
}
}
}


Is there any good solution or relative design pattern can solve this problem Elegant and Clean ? Thanks a lot.







oop design-patterns polymorphism factory-pattern






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 '18 at 17:34









王予智王予智

111




111













  • Instead of passing a product_id to your 'produce' method, you could pass an object that is polymorphic. Let's say the base class of that object only contains the product_id, but then you could subclass it and potentially add parameters to it based on your use-case.

    – AlexG
    Nov 19 '18 at 17:39













  • @AlexG, thanks for your comment. But what is the different between this method and pass (product_id, db). Because the Factory return Product mostly base on product_id, and sometime it need additional information, say db, and I don't know when will it be required. So how can I determine whether to pass BaseClass with product_id or DeriveClass with (product_id, db)?

    – 王予智
    Nov 19 '18 at 17:53











  • I have no idea of your use-case, but it feels like if you need to add parameters or do a bunch of conditional stuff, then the factory pattern isn't the right choice. My approach was to provide a single function signature and be able to pass in different parameters, which implies the caller knows a few things about what will be instantiated.

    – AlexG
    Nov 19 '18 at 18:30











  • My detail use-case is that I'm working MVC web page where I need to process data from a row of database column (e.x. GET ? product_id=1). Because I need to use different strategy to process the data base on product_id, so I pass product_id to a Factory and get relevant class to process it. However, during some special product, I need to query more data from database, so I need the reference of $this->db from Codeigniter controller to pass to the derive object that produce by Factory

    – 王予智
    Nov 19 '18 at 18:44



















  • Instead of passing a product_id to your 'produce' method, you could pass an object that is polymorphic. Let's say the base class of that object only contains the product_id, but then you could subclass it and potentially add parameters to it based on your use-case.

    – AlexG
    Nov 19 '18 at 17:39













  • @AlexG, thanks for your comment. But what is the different between this method and pass (product_id, db). Because the Factory return Product mostly base on product_id, and sometime it need additional information, say db, and I don't know when will it be required. So how can I determine whether to pass BaseClass with product_id or DeriveClass with (product_id, db)?

    – 王予智
    Nov 19 '18 at 17:53











  • I have no idea of your use-case, but it feels like if you need to add parameters or do a bunch of conditional stuff, then the factory pattern isn't the right choice. My approach was to provide a single function signature and be able to pass in different parameters, which implies the caller knows a few things about what will be instantiated.

    – AlexG
    Nov 19 '18 at 18:30











  • My detail use-case is that I'm working MVC web page where I need to process data from a row of database column (e.x. GET ? product_id=1). Because I need to use different strategy to process the data base on product_id, so I pass product_id to a Factory and get relevant class to process it. However, during some special product, I need to query more data from database, so I need the reference of $this->db from Codeigniter controller to pass to the derive object that produce by Factory

    – 王予智
    Nov 19 '18 at 18:44

















Instead of passing a product_id to your 'produce' method, you could pass an object that is polymorphic. Let's say the base class of that object only contains the product_id, but then you could subclass it and potentially add parameters to it based on your use-case.

– AlexG
Nov 19 '18 at 17:39







Instead of passing a product_id to your 'produce' method, you could pass an object that is polymorphic. Let's say the base class of that object only contains the product_id, but then you could subclass it and potentially add parameters to it based on your use-case.

– AlexG
Nov 19 '18 at 17:39















@AlexG, thanks for your comment. But what is the different between this method and pass (product_id, db). Because the Factory return Product mostly base on product_id, and sometime it need additional information, say db, and I don't know when will it be required. So how can I determine whether to pass BaseClass with product_id or DeriveClass with (product_id, db)?

– 王予智
Nov 19 '18 at 17:53





@AlexG, thanks for your comment. But what is the different between this method and pass (product_id, db). Because the Factory return Product mostly base on product_id, and sometime it need additional information, say db, and I don't know when will it be required. So how can I determine whether to pass BaseClass with product_id or DeriveClass with (product_id, db)?

– 王予智
Nov 19 '18 at 17:53













I have no idea of your use-case, but it feels like if you need to add parameters or do a bunch of conditional stuff, then the factory pattern isn't the right choice. My approach was to provide a single function signature and be able to pass in different parameters, which implies the caller knows a few things about what will be instantiated.

– AlexG
Nov 19 '18 at 18:30





I have no idea of your use-case, but it feels like if you need to add parameters or do a bunch of conditional stuff, then the factory pattern isn't the right choice. My approach was to provide a single function signature and be able to pass in different parameters, which implies the caller knows a few things about what will be instantiated.

– AlexG
Nov 19 '18 at 18:30













My detail use-case is that I'm working MVC web page where I need to process data from a row of database column (e.x. GET ? product_id=1). Because I need to use different strategy to process the data base on product_id, so I pass product_id to a Factory and get relevant class to process it. However, during some special product, I need to query more data from database, so I need the reference of $this->db from Codeigniter controller to pass to the derive object that produce by Factory

– 王予智
Nov 19 '18 at 18:44





My detail use-case is that I'm working MVC web page where I need to process data from a row of database column (e.x. GET ? product_id=1). Because I need to use different strategy to process the data base on product_id, so I pass product_id to a Factory and get relevant class to process it. However, during some special product, I need to query more data from database, so I need the reference of $this->db from Codeigniter controller to pass to the derive object that produce by Factory

– 王予智
Nov 19 '18 at 18:44












1 Answer
1






active

oldest

votes


















0














The downside with your solution is that, every client of the Factory must have a Database in order to call the produce method.



So you can use the Abstract Factory pattern here:



interface AbstractFactory {
AbstractProduct produce();
}

class Factory_A implements AbstractFactory {
AbstractProduct produce() { return new Product_A(); }
}

class Factory_B implements AbstractFactory {
private Database db;
public Factory_B(Database db) { this.db = db; }
AbstractProduct produce() { return new Product_B(db); }
}

class Client {
private AbstractFactory factory;
public Client(AbstractFactory factory) { this.factory = factory; }
public void foo() {
AbstractProduct product = factory.produce();
// ...
}
}

void main() {
AbstractFactory factory = random() == 1 ?
new Factory_A() :
new Factory_B(new Database(...));

print(factory.produce().getDetail());

Client client = new Client(factory);
client.foo();
}


Hope this helps.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53379904%2fpolymorphism-addition-parameter-pass-to-constructor-of-derived-class-in-factor%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    The downside with your solution is that, every client of the Factory must have a Database in order to call the produce method.



    So you can use the Abstract Factory pattern here:



    interface AbstractFactory {
    AbstractProduct produce();
    }

    class Factory_A implements AbstractFactory {
    AbstractProduct produce() { return new Product_A(); }
    }

    class Factory_B implements AbstractFactory {
    private Database db;
    public Factory_B(Database db) { this.db = db; }
    AbstractProduct produce() { return new Product_B(db); }
    }

    class Client {
    private AbstractFactory factory;
    public Client(AbstractFactory factory) { this.factory = factory; }
    public void foo() {
    AbstractProduct product = factory.produce();
    // ...
    }
    }

    void main() {
    AbstractFactory factory = random() == 1 ?
    new Factory_A() :
    new Factory_B(new Database(...));

    print(factory.produce().getDetail());

    Client client = new Client(factory);
    client.foo();
    }


    Hope this helps.






    share|improve this answer




























      0














      The downside with your solution is that, every client of the Factory must have a Database in order to call the produce method.



      So you can use the Abstract Factory pattern here:



      interface AbstractFactory {
      AbstractProduct produce();
      }

      class Factory_A implements AbstractFactory {
      AbstractProduct produce() { return new Product_A(); }
      }

      class Factory_B implements AbstractFactory {
      private Database db;
      public Factory_B(Database db) { this.db = db; }
      AbstractProduct produce() { return new Product_B(db); }
      }

      class Client {
      private AbstractFactory factory;
      public Client(AbstractFactory factory) { this.factory = factory; }
      public void foo() {
      AbstractProduct product = factory.produce();
      // ...
      }
      }

      void main() {
      AbstractFactory factory = random() == 1 ?
      new Factory_A() :
      new Factory_B(new Database(...));

      print(factory.produce().getDetail());

      Client client = new Client(factory);
      client.foo();
      }


      Hope this helps.






      share|improve this answer


























        0












        0








        0







        The downside with your solution is that, every client of the Factory must have a Database in order to call the produce method.



        So you can use the Abstract Factory pattern here:



        interface AbstractFactory {
        AbstractProduct produce();
        }

        class Factory_A implements AbstractFactory {
        AbstractProduct produce() { return new Product_A(); }
        }

        class Factory_B implements AbstractFactory {
        private Database db;
        public Factory_B(Database db) { this.db = db; }
        AbstractProduct produce() { return new Product_B(db); }
        }

        class Client {
        private AbstractFactory factory;
        public Client(AbstractFactory factory) { this.factory = factory; }
        public void foo() {
        AbstractProduct product = factory.produce();
        // ...
        }
        }

        void main() {
        AbstractFactory factory = random() == 1 ?
        new Factory_A() :
        new Factory_B(new Database(...));

        print(factory.produce().getDetail());

        Client client = new Client(factory);
        client.foo();
        }


        Hope this helps.






        share|improve this answer













        The downside with your solution is that, every client of the Factory must have a Database in order to call the produce method.



        So you can use the Abstract Factory pattern here:



        interface AbstractFactory {
        AbstractProduct produce();
        }

        class Factory_A implements AbstractFactory {
        AbstractProduct produce() { return new Product_A(); }
        }

        class Factory_B implements AbstractFactory {
        private Database db;
        public Factory_B(Database db) { this.db = db; }
        AbstractProduct produce() { return new Product_B(db); }
        }

        class Client {
        private AbstractFactory factory;
        public Client(AbstractFactory factory) { this.factory = factory; }
        public void foo() {
        AbstractProduct product = factory.produce();
        // ...
        }
        }

        void main() {
        AbstractFactory factory = random() == 1 ?
        new Factory_A() :
        new Factory_B(new Database(...));

        print(factory.produce().getDetail());

        Client client = new Client(factory);
        client.foo();
        }


        Hope this helps.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 4:35









        Nghia BuiNghia Bui

        1,453813




        1,453813






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53379904%2fpolymorphism-addition-parameter-pass-to-constructor-of-derived-class-in-factor%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?