(Polymorphism) Addition parameter pass to constructor of derived class in factory pattern
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
add a comment |
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
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 theFactory
returnProduct
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 passBaseClass
with product_id orDeriveClass
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 aFactory
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 byFactory
– 王予智
Nov 19 '18 at 18:44
add a comment |
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
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
oop design-patterns polymorphism factory-pattern
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 theFactory
returnProduct
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 passBaseClass
with product_id orDeriveClass
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 aFactory
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 byFactory
– 王予智
Nov 19 '18 at 18:44
add a comment |
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 theFactory
returnProduct
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 passBaseClass
with product_id orDeriveClass
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 aFactory
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 byFactory
– 王予智
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
add a comment |
1 Answer
1
active
oldest
votes
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 20 '18 at 4:35
Nghia BuiNghia Bui
1,453813
1,453813
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
returnProduct
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 passBaseClass
with product_id orDeriveClass
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 byFactory
– 王予智
Nov 19 '18 at 18:44