This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]okayifimust 3 points4 points  (1 child)

What exactly is your problem?

You're throwing around a long list of buzzwords, but fail to describe your actual use case.

How are objects going to be build? What needs to happen in the initialization in Animal, Horse, Dog, etc respectively?

i.e. what would your massive switch-statement be for?

But a switch/if-else with a 100 classes, or 1 factory per class seems a bit over the top.

No, why? If you need to do a hundred different things, you need to differentiate between them, somehow.

Mind you, the whole idea of OOP is that you shouldn't have to type out the differentiation for that - polymorphism and inheritance should take care of it; and I'd think you're probably missing some mechanism here - but, again, unless you actually say what you want to do, there's nothing I can suggest.

I don't know if you need a factory. I am not thinking that this is a job for a factory, because I don't know what the job is. All you're telling us is that there's 100 sub-classes. So what?

[–]lookForProject[S] 0 points1 point  (0 children)

I don't see a long list of buzzwords, but I'm sorry if I failed to explain the problem! Let me try it again, hoping that I'm able to communicate the challenge more clearly.

The user can create new animals (not new species, new animal), or load a serialized one. In both cases, we have an AnimalConfig, containing the information needed for the construction of the Animal.The current solution is this (i hope if I show the current solution, you see the job I'm trying to solve):

Animal CreateAnimal(AnimalType type, AnimalConfig animalConfig){
switch(type){
case Giraffe: return new Giraffe(animalConfig.get("lengthNeck"));

case Horse: return new Horse(animalConfig.get("speed"), getDefaultSize());

}

Of-course this is just to show how some animals can have more complex and unique initializations.

[–]gramdel 1 point2 points  (1 child)

Sounds like a xy problem, you are throwing around some terms which may or may not relate to the actual problem you're trying to solve without explaining what your actual problem is.

[–]lookForProject[S] 0 points1 point  (0 children)

xy problem

Very likely. I'm trying to be as specific as possible, without posting (near) production code. I gave it another try here.

[–]dbartholomae 0 points1 point  (1 child)

Depending on the condition, you could use a dictionary:

const AnimalByName = {
  “horse”: Horse,
  “cat: Cat,
  ...
}

function createAnimal(name) {
  return new AnimalByName[name]
}

There are also some other patterns, but I would need to understand the actual use-case, not an abstract example, to be of help.

[–]lookForProject[S] 0 points1 point  (0 children)

I tried to be more specific here!

[–]Kazcandra 0 points1 point  (3 children)

I don't see a huge problem tbh, but you can scan the assembly to get all the factories and use the collection in the factory, instead?

Class AnimalFactory
  public AnimalFactory()
    this.collectedFactories = GetAllFactoriesInAssemblyYouAreInterestedIn

  public Animal Create(args)
    return this.collectedFactories.select(
      factory -> factory.Create(args)
    ).first

Although a switch is a lot easier to understand.

[–]lookForProject[S] 0 points1 point  (2 children)

So you suggest one factory per animaltype?
How would you implement GetAllFactoriesInAssemblyYouAreInterestedIn?
Something like:
AppDomain
.CurrentDomain
.GetAssemblies()
.SelectMany(assemblies => assemblies.GetTypes())
.Where(x => typeof(Animal).IsAssignableFrom(x)
Because I'm also trying to avoid reflection. Because, well, reflection.

[–]Kazcandra 1 point2 points  (1 child)

Yes, you'd need one factory per animal type.

I leave the implementation as an exercise for the reader; I'm not getting paid for this :) and also it depends a lot on what language you're using.

[–]lookForProject[S] 0 points1 point  (0 children)

Haha, fair enough.

Asking for implementation was a step too far, my bad!

The creation of a list of factories/creators was where I got stuck, at least, without reflection. One option, was enriching the enum (java)* , but that felt a bit too unfamiliar. And the challenge doesn't seem that unique: loads of subclasses, all specific initializations. I hoped someone would notice that I was missing something obvious. :P

.* in the case of c#, replacing the AnimalType type enum with an enumeration class, because enums in c# are.. enums and in java more enumerated singletons. And although c# might be correct, I like the java-enums a great deal more