Re: Factory pattern for classes

2020-08-10 Thread Martin via Digitalmars-d-learn

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.


Re: Factory pattern for classes

2020-08-10 Thread Ali Çehreli via Digitalmars-d-learn

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


Re: Factory pattern for classes

2020-08-10 Thread lexxn via Digitalmars-d-learn

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();
}

Ali


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")


Re: Factory pattern for classes

2020-08-09 Thread lexxn via Digitalmars-d-learn

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();
}

Ali


This is the solution I will use, at least for now. Thank you Ali.



Re: Factory pattern for classes

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/20 10:27 AM, lexxn wrote:

On Sunday, 9 August 2020 at 12:24:05 UTC, Steven Schveighoffer wrote:



Object 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.


If the constructor has no parameters, classes can be new'd without 
parentheses, so your modification results in identical code as my example.


-Steve


Re: Factory pattern for classes

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/9/20 10:58 AM, lexxn wrote:

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.


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.

-Steve


Re: Factory pattern for classes

2020-08-09 Thread Ali Çehreli via Digitalmars-d-learn

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 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



Re: Factory pattern for classes

2020-08-09 Thread lexxn via Digitalmars-d-learn
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.


Re: Factory pattern for classes

2020-08-09 Thread lexxn via Digitalmars-d-learn
On Sunday, 9 August 2020 at 12:24:05 UTC, Steven Schveighoffer 
wrote:

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


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 classes when I try 
to call it with myClass I get no property methodName for type 
object.Object.




Re: Factory pattern for classes

2020-08-09 Thread Steven Schveighoffer via Digitalmars-d-learn

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