digitalmars.D.learn - Factory pattern for classes
- lexxn (21/21) Aug 09 2020 I'm trying to get the factory pattern going with classes
- Steven Schveighoffer (18/43) Aug 09 2020 This won't work.
- lexxn (16/59) Aug 09 2020 I assume that the correct syntax for the getClassById is
- =?UTF-8?Q?Ali_=c3=87ehreli?= (41/55) Aug 09 2020 Because those example classes are not a part of a hierarchy, their
- lexxn (2/38) Aug 09 2020 This is the solution I will use, at least for now. Thank you Ali.
- lexxn (4/20) Aug 10 2020 Btw is it possible to pass a property to the constructor, if I've
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/7) Aug 10 2020 I think you mean "parameter". No, Object.factory creates the object with...
- Martin (5/35) Aug 10 2020 Then you can also pass parameters to the constructors or call
- Steven Schveighoffer (4/28) Aug 09 2020 If the constructor has no parameters, classes can be new'd without
- lexxn (5/8) Aug 09 2020 Not sure if it's a good idea in my case. I'm going to be using
- Steven Schveighoffer (5/14) Aug 09 2020 My point is -- it's a good idea to not use Object.factory, because it's
I'm trying to get the factory pattern going with classes class A {} class B {} class C {} auto getClassById(uint id) { if (id == 0) { return cast(A)Object.factory("A"); } else if(id == 1) { return cast(B)Object.factory("B"); } else { return cast(C)Object.factory("C"); } } I'm getting 2 errors: main.d(69): Error: Expected return type of main.A, not main.B: main.d(67): Return type of main.Ainferred here. Also is it possible to completely skip the getClassById function and if I've and array string classes = ["A", "B"] to just cast(classes[0])Object.factory(classes[0]);. I understand that I need to cast classes[0].
Aug 09 2020
On 8/9/20 5:16 AM, lexxn wrote:I'm trying to get the factory pattern going with classes class A {} class B {} class C {} auto getClassById(uint id) { if (id == 0) { return cast(A)Object.factory("A"); } else if(id == 1) { return cast(B)Object.factory("B"); } else { return cast(C)Object.factory("C"); } } I'm getting 2 errors: main.d(69): Error: Expected return type of main.A, not main.B: main.d(67): Return type of main.Ainferred here.Change your return type to Object.Also is it possible to completely skip the getClassById function and if I've and array string classes = ["A", "B"] to just cast(classes[0])Object.factory(classes[0]);. I understand that I need to cast classes[0].This won't work. If you know what your class is going to be, I'd just import the file that contains it and avoid the whole Object.factory deal. It's going to go away anyways. In other words: Object getClassById(uint id) { if (id == 0) { return new A; } else if(id == 1) { return new B; } else { return new C; } } -Steve
Aug 09 2020
On Sunday, 9 August 2020 at 12:24:05 UTC, Steven Schveighoffer wrote:On 8/9/20 5:16 AM, lexxn wrote:I assume that the correct syntax for the getClassById is Object getClassById(uint id) { if (id == 0) { return new A(); } else if (id == 1) { return new B(); } else { return new C(); } } or maybe I'm wrong. This way if I try auto myClass = getClassById(0) and if I've a method in A,B&C classes when I try to call it with myClass I get no property methodName for type object.Object.I'm trying to get the factory pattern going with classes class A {} class B {} class C {} auto getClassById(uint id) { if (id == 0) { return cast(A)Object.factory("A"); } else if(id == 1) { return cast(B)Object.factory("B"); } else { return cast(C)Object.factory("C"); } } I'm getting 2 errors: main.d(69): Error: Expected return type of main.A, not main.B: main.d(67): Return type of main.Ainferred here.Change your return type to Object.Also is it possible to completely skip the getClassById function and if I've and array string classes = ["A", "B"] to just cast(classes[0])Object.factory(classes[0]);. I understand that I need to cast classes[0].This won't work. If you know what your class is going to be, I'd just import the file that contains it and avoid the whole Object.factory deal. It's going to go away anyways. In other words: Object getClassById(uint id) { if (id == 0) { return new A; } else if(id == 1) { return new B; } else { return new C; } } -Steve
Aug 09 2020
On 8/9/20 7:27 AM, lexxn wrote:I assume that the correct syntax for the getClassById is Object getClassById(uint id) { if (id == 0) { return new A(); } else if (id == 1) { return new B(); } else { return new C(); } } or maybe I'm wrong.Because those example classes are not a part of a hierarchy, their common interface is Object. That is the only way to get the code compile.This way if I try auto myClass = getClassById(0) and if I've a method in A,B&C classes when I try to call it with myClass I get no property methodName for type object.Object.If methodName() is a virtual function of your hierarchy, then normally it is a part of an interface that all those classes implement and the return type is that common ancestor. Here is a working example: module deneme; import std.stdio; interface I { void methodName(); } class A : I { void methodName() { writeln("A"); } } class B : I { void methodName() { writeln("B"); } } class C : I { void methodName() { writeln("C"); } } I getClassById(uint id) { if (id == 0) { return cast(A)Object.factory("deneme.A"); } else if(id == 1) { return cast(B)Object.factory("deneme.B"); } else { return cast(C)Object.factory("deneme.C"); } } void main() { auto o = getClassById(1); o.methodName(); } Ali
Aug 09 2020
On Sunday, 9 August 2020 at 15:56:31 UTC, Ali Çehreli wrote:On 8/9/20 7:27 AM, lexxn wrote: module deneme; import std.stdio; interface I { void methodName(); } class A : I { void methodName() { writeln("A"); } } class B : I { void methodName() { writeln("B"); } } class C : I { void methodName() { writeln("C"); } } I getClassById(uint id) { if (id == 0) { return cast(A)Object.factory("deneme.A"); } else if(id == 1) { return cast(B)Object.factory("deneme.B"); } else { return cast(C)Object.factory("deneme.C"); } } void main() { auto o = getClassById(1); o.methodName(); } AliThis is the solution I will use, at least for now. Thank you Ali.
Aug 09 2020
On Sunday, 9 August 2020 at 15:56:31 UTC, Ali Çehreli wrote:On 8/9/20 7:27 AM, lexxn wrote: I getClassById(uint id) { if (id == 0) { return cast(A)Object.factory("deneme.A"); } else if(id == 1) { return cast(B)Object.factory("deneme.B"); } else { return cast(C)Object.factory("deneme.C"); } } void main() { auto o = getClassById(1); o.methodName(); } AliBtw is it possible to pass a property to the constructor, if I've one declared, in the factory? I'm talking about this piece cast(A)Object.factory("deneme.A")
Aug 10 2020
On 8/10/20 8:38 AM, lexxn wrote:Btw is it possible to pass a property to the constructor, if I've one declared, in the factory? I'm talking about this piece cast(A)Object.factory("deneme.A")I think you mean "parameter". No, Object.factory creates the object with its default constructor. Ali
Aug 10 2020
On Sunday, 9 August 2020 at 15:56:31 UTC, Ali Çehreli wrote:module deneme; import std.stdio; interface I { void methodName(); } ... I getClassById(uint id) { if (id == 0) { return cast(A)Object.factory("deneme.A"); } else if(id == 1) { return cast(B)Object.factory("deneme.B"); } else { return cast(C)Object.factory("deneme.C"); } } void main() { auto o = getClassById(1); o.methodName(); }Why not simply do?I getClassById(uint id) { if (id == 0) { return new A(); } else if(id == 1) { return new B(); } else { return new C(); } }Then you can also pass parameters to the constructors or call further factories to create them, as long as they return a `I`-compatible type.
Aug 10 2020
On 8/9/20 10:27 AM, lexxn wrote:On Sunday, 9 August 2020 at 12:24:05 UTC, Steven Schveighoffer wrote:If the constructor has no parameters, classes can be new'd without parentheses, so your modification results in identical code as my example. -SteveObject getClassById(uint id) { if (id == 0) { return new A; } else if(id == 1) { return new B; } else { return new C; } }I assume that the correct syntax for the getClassById is Object getClassById(uint id) { if (id == 0) { return new A(); } else if (id == 1) { return new B(); } else { return new C(); } } or maybe I'm wrong.
Aug 09 2020
On Sunday, 9 August 2020 at 12:24:05 UTC, Steven Schveighoffer wrote:If you know what your class is going to be, I'd just import the file that contains it and avoid the whole Object.factory deal. It's going to go away anyways.Not sure if it's a good idea in my case. I'm going to be using all of the classes eventually in my loop, but I just need to initialize them in a conditional way depending on the use case.
Aug 09 2020
On 8/9/20 10:58 AM, lexxn wrote:On Sunday, 9 August 2020 at 12:24:05 UTC, Steven Schveighoffer wrote:My point is -- it's a good idea to not use Object.factory, because it's going to go away. It doesn't work in all cases anyway. -SteveIf you know what your class is going to be, I'd just import the file that contains it and avoid the whole Object.factory deal. It's going to go away anyways.Not sure if it's a good idea in my case. I'm going to be using all of the classes eventually in my loop, but I just need to initialize them in a conditional way depending on the use case.
Aug 09 2020