Jump to page: 1 2
Thread overview
Factory pattern for classes
Aug 09, 2020
lexxn
Aug 09, 2020
lexxn
Aug 09, 2020
Ali Çehreli
Aug 09, 2020
lexxn
Aug 10, 2020
lexxn
Aug 10, 2020
Ali Çehreli
Aug 10, 2020
Martin
Aug 09, 2020
lexxn
August 09, 2020
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].
August 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
August 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'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&C classes when I try to call it with myClass I get no property methodName for type object.Object.

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

August 09, 2020
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
August 09, 2020
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
August 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();
> }
>
> Ali

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

August 10, 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();
> }
>
> 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")
August 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
« First   ‹ Prev
1 2