Jump to page: 1 2
Thread overview
Factory pattern in D
May 01, 2015
Chris
May 01, 2015
Namespace
May 01, 2015
Namespace
May 01, 2015
Chris
May 01, 2015
biozic
May 01, 2015
Chris
May 01, 2015
Chris
May 01, 2015
Chris
May 01, 2015
biozic
May 01, 2015
Chris
May 01, 2015
biozic
May 01, 2015
anonymous
May 01, 2015
Rikki Cattermole
May 01, 2015
What would be the D equivalent of the factory pattern? This obviously doesn't work:

struct A {
  int x = 42;
}

struct B {
  int x = 7;
}

auto factory(string type) {
  if (type == "A")
    return A();
  else if (type == "B")
    return B();
  else
    return A();  // default
}

void main()
{
  auto a = factory("A");
}

Error: mismatched function return type inference of B and A

(dmd 2.067.1)
May 01, 2015
How about this:

----
struct A {
  int x = 42;
}

struct B {
  int x = 7;
}

T factory(T)() {
  return T();
}

void main()
{
  auto a = factory!(A);
}
----
May 01, 2015
On 1/05/2015 10:01 p.m., Chris wrote:
> What would be the D equivalent of the factory pattern? This obviously
> doesn't work:
>
> struct A {
>    int x = 42;
> }
>
> struct B {
>    int x = 7;
> }
>
> auto factory(string type) {
>    if (type == "A")
>      return A();
>    else if (type == "B")
>      return B();
>    else
>      return A();  // default
> }
>
> void main()
> {
>    auto a = factory("A");
> }
>
> Error: mismatched function return type inference of B and A
>
> (dmd 2.067.1)

Interfaces/classes not structs.
May 01, 2015
On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote:
> How about this:
>
> ----
> struct A {
>   int x = 42;
> }
>
> struct B {
>   int x = 7;
> }
>
> T factory(T)() {
>   return T();
> }
>
> void main()
> {
>   auto a = factory!(A);
> }
> ----

Of course, you can restrict the type to A or B, or both:
----
T factory(T)() if (is(T == A) || is(T == B)) {
  return T();
}
----
May 01, 2015
On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote:
> How about this:
>
> ----
> struct A {
>   int x = 42;
> }
>
> struct B {
>   int x = 7;
> }
>
> T factory(T)() {
>   return T();
> }
>
> void main()
> {
>   auto a = factory!(A);
> }
> ----

That's what I was looking for, I just couldn't get it right. Thanks.

Rikki:

I wanted to avoid classes and interfaces.
May 01, 2015
On Friday, 1 May 2015 at 10:12:36 UTC, Chris wrote:
> On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote:
>> How about this:
>>
>> ----
>> struct A {
>>  int x = 42;
>> }
>>
>> struct B {
>>  int x = 7;
>> }
>>
>> T factory(T)() {
>>  return T();
>> }
>>
>> void main()
>> {
>>  auto a = factory!(A);
>> }
>> ----
>
> That's what I was looking for, I just couldn't get it right. Thanks.
>
> Rikki:
>
> I wanted to avoid classes and interfaces.

This might be a bit more useful:
---
struct A {
  int x = 42;
}

struct B {
  int x = 7;
}

auto factory(string type = "")() {
  static if (type == "A")
    return A();
  else static if (type == "B")
    return B();
  else
    return A();  // default
}

void main()
{
  auto a = factory!"A";
  auto b = factory!"B";
  auto x = factory;
}
---


May 01, 2015
On Friday, 1 May 2015 at 10:27:16 UTC, biozic wrote:
> On Friday, 1 May 2015 at 10:12:36 UTC, Chris wrote:
>> On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote:
>>> How about this:
>>>
>>> ----
>>> struct A {
>>> int x = 42;
>>> }
>>>
>>> struct B {
>>> int x = 7;
>>> }
>>>
>>> T factory(T)() {
>>> return T();
>>> }
>>>
>>> void main()
>>> {
>>> auto a = factory!(A);
>>> }
>>> ----
>>
>> That's what I was looking for, I just couldn't get it right. Thanks.
>>
>> Rikki:
>>
>> I wanted to avoid classes and interfaces.
>
> This might be a bit more useful:
> ---
> struct A {
>   int x = 42;
> }
>
> struct B {
>   int x = 7;
> }
>
> auto factory(string type = "")() {
>   static if (type == "A")
>     return A();
>   else static if (type == "B")
>     return B();
>   else
>     return A();  // default
> }
>
> void main()
> {
>   auto a = factory!"A";
>   auto b = factory!"B";
>   auto x = factory;
> }
> ---

Duh, I tried `static if` yesterday and I still got "Error: mismatched function return type inference of B and A". Now it works! Sure, I must have overlooked something. Sometimes it's better to go home and call it a day than to try to get something to work.
May 01, 2015
On Friday, 1 May 2015 at 10:46:20 UTC, Chris wrote:
> On Friday, 1 May 2015 at 10:27:16 UTC, biozic wrote:
>> On Friday, 1 May 2015 at 10:12:36 UTC, Chris wrote:
>>> On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote:
>>>> How about this:
>>>>
>>>> ----
>>>> struct A {
>>>> int x = 42;
>>>> }
>>>>
>>>> struct B {
>>>> int x = 7;
>>>> }
>>>>
>>>> T factory(T)() {
>>>> return T();
>>>> }
>>>>
>>>> void main()
>>>> {
>>>> auto a = factory!(A);
>>>> }
>>>> ----
>>>
>>> That's what I was looking for, I just couldn't get it right. Thanks.
>>>
>>> Rikki:
>>>
>>> I wanted to avoid classes and interfaces.
>>
>> This might be a bit more useful:
>> ---
>> struct A {
>>  int x = 42;
>> }
>>
>> struct B {
>>  int x = 7;
>> }
>>
>> auto factory(string type = "")() {
>>  static if (type == "A")
>>    return A();
>>  else static if (type == "B")
>>    return B();
>>  else
>>    return A();  // default
>> }
>>
>> void main()
>> {
>>  auto a = factory!"A";
>>  auto b = factory!"B";
>>  auto x = factory;
>> }
>> ---
>
> Duh, I tried `static if` yesterday and I still got "Error: mismatched function return type inference of B and A". Now it works! Sure, I must have overlooked something. Sometimes it's better to go home and call it a day than to try to get something to work.

And thanks, by the way!
May 01, 2015
On Friday, 1 May 2015 at 10:47:22 UTC, Chris wrote:
> On Friday, 1 May 2015 at 10:46:20 UTC, Chris wrote:
>> On Friday, 1 May 2015 at 10:27:16 UTC, biozic wrote:
>>> On Friday, 1 May 2015 at 10:12:36 UTC, Chris wrote:
>>>> On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote:
>>>>> How about this:
>>>>>
>>>>> ----
>>>>> struct A {
>>>>> int x = 42;
>>>>> }
>>>>>
>>>>> struct B {
>>>>> int x = 7;
>>>>> }
>>>>>
>>>>> T factory(T)() {
>>>>> return T();
>>>>> }
>>>>>
>>>>> void main()
>>>>> {
>>>>> auto a = factory!(A);
>>>>> }
>>>>> ----
>>>>
>>>> That's what I was looking for, I just couldn't get it right. Thanks.
>>>>
>>>> Rikki:
>>>>
>>>> I wanted to avoid classes and interfaces.
>>>
>>> This might be a bit more useful:
>>> ---
>>> struct A {
>>> int x = 42;
>>> }
>>>
>>> struct B {
>>> int x = 7;
>>> }
>>>
>>> auto factory(string type = "")() {
>>> static if (type == "A")
>>>   return A();
>>> else static if (type == "B")
>>>   return B();
>>> else
>>>   return A();  // default
>>> }
>>>
>>> void main()
>>> {
>>> auto a = factory!"A";
>>> auto b = factory!"B";
>>> auto x = factory;
>>> }
>>> ---
>>
>> Duh, I tried `static if` yesterday and I still got "Error: mismatched function return type inference of B and A". Now it works! Sure, I must have overlooked something. Sometimes it's better to go home and call it a day than to try to get something to work.
>
> And thanks, by the way!

Thinking about it,

T factory(T)() {
  return T();
}

is better suited for a factory (with static type checks).

This aside, how would I get something to load dynamically? It's either "mismatched function return type" or (with type check) "variable X cannot be read at compile time":

void main(string[] args) {
 auto type = args[1];
 auto myType = factory!type();
}

So it's back to classes/interfaces again? Hmmmm.
May 01, 2015
On Friday, 1 May 2015 at 11:01:29 UTC, Chris wrote:
> On Friday, 1 May 2015 at 10:47:22 UTC, Chris wrote:
>> On Friday, 1 May 2015 at 10:46:20 UTC, Chris wrote:
>>> On Friday, 1 May 2015 at 10:27:16 UTC, biozic wrote:
>>>> On Friday, 1 May 2015 at 10:12:36 UTC, Chris wrote:
>>>>> On Friday, 1 May 2015 at 10:04:46 UTC, Namespace wrote:
>>>>>> How about this:
>>>>>>
>>>>>> ----
>>>>>> struct A {
>>>>>> int x = 42;
>>>>>> }
>>>>>>
>>>>>> struct B {
>>>>>> int x = 7;
>>>>>> }
>>>>>>
>>>>>> T factory(T)() {
>>>>>> return T();
>>>>>> }
>>>>>>
>>>>>> void main()
>>>>>> {
>>>>>> auto a = factory!(A);
>>>>>> }
>>>>>> ----
>>>>>
>>>>> That's what I was looking for, I just couldn't get it right. Thanks.
>>>>>
>>>>> Rikki:
>>>>>
>>>>> I wanted to avoid classes and interfaces.
>>>>
>>>> This might be a bit more useful:
>>>> ---
>>>> struct A {
>>>> int x = 42;
>>>> }
>>>>
>>>> struct B {
>>>> int x = 7;
>>>> }
>>>>
>>>> auto factory(string type = "")() {
>>>> static if (type == "A")
>>>>  return A();
>>>> else static if (type == "B")
>>>>  return B();
>>>> else
>>>>  return A();  // default
>>>> }
>>>>
>>>> void main()
>>>> {
>>>> auto a = factory!"A";
>>>> auto b = factory!"B";
>>>> auto x = factory;
>>>> }
>>>> ---
>>>
>>> Duh, I tried `static if` yesterday and I still got "Error: mismatched function return type inference of B and A". Now it works! Sure, I must have overlooked something. Sometimes it's better to go home and call it a day than to try to get something to work.
>>
>> And thanks, by the way!
>
> Thinking about it,
>
> T factory(T)() {
>   return T();
> }
>
> is better suited for a factory (with static type checks).

But then I don't know what factory!X() provides that X() alone doesn't.

> This aside, how would I get something to load dynamically? It's either "mismatched function return type" or (with type check) "variable X cannot be read at compile time":
>
> void main(string[] args) {
>  auto type = args[1];
>  auto myType = factory!type();
> }
>
> So it's back to classes/interfaces again? Hmmmm.

Indeed. Runtime polymorphism is based on classes and interfaces. The struct and template solutions can only make "compile-time factories".

« First   ‹ Prev
1 2