3 ms·
Factories are a perfectly good solution to the problem of "I have numerous possible ways of carrying out task X, and I want to use one of them that will not be
by AndrewDucker 15y ago
Factories are a perfectly good solution to the problem of "I have numerous possible ways of carrying out task X, and I want to use one of them that will not be specified until the application is running."
So if I want to write some input to a user-defined place then giving the user the list of options and then passing the option to a WriterFactory to give me the correct Writer makes sense. You have to put the choice of which Writer to use in different scenarios somewhere, so why not a class by itself?
- Bjartr 15y agoWhy not an if statement?
- AndrewDucker 15y agoOk, but where does the if statement go, particularly if it's reused in a few places, from different classes? Putting it into a util class by itself seems like a reasonable thing to do in that case.
- fleitz 15y agoFactories are a good way to solve the problem of not being able to pass a function that creates an object. They're generally an OO kludge around passing an anonymous function, because for some reason passing a function needs to be insanely difficult. And so another class is created to manage the thing that the constructor was supposed to do in the first place (manage the creation of objects) but if you called it the constructor pattern they'd have to admit the language was broken. OO languages that support passing functions generally don't have very many instances of the factory pattern, and languages that have abstracted allocation of memory and initialization of memory have even fewer instances of it. That's why I consider the factory pattern to be an anti-pattern; you've chosen a language that's ill suited to the task you are solving and instead of fixing the real problem (can't pass functions that create objects in a reasonable amount of effort) you're inventing kludges. I've only seen a handful of cases where accepting a parameter of type () -> T or x -> T doesn't solve the factory pattern issue.
- AndrewDucker 15y agoI don't understand, I'm afraid. How does function passing negate the need to choose between multiple implementors of an interface?
- fleitz 15y agoThe interface of a factory pattern is generally a single method, so most factory patterns are an interface with a single function. Normally a factory class looks like this: class MyFooFactory : FooFactory { Foo createFoo() { return new MyKindOfFoo(); } } createFoo has a type of () -> Foo, that is to say a function that takes no parameters an returns an object of class Foo. Sometimes the pattern is String -> Foo, but the more general case is () -> T When you need to use a factory you'll create it and then pass it to the object like: FooFactory f = new MyFooFactory(); FooUser fu = new FooUser(f); fu.doSomething(); And FooUser will have some method in it that does something like public doSomething() { Foo foo = fooFactory.createFoo(); // does something with the foo. } If FooUser took a parameter of () -> Foo instead of FooFactory your code would now look like this: FooUser fu = new FooUser(() => new MyKindOfFoo()); fu.doSomething();
- AndrewDucker 15y agoYes, in the case where a Factory class contains one method that takes no parameters and just contains a "new" call, you can get rid of the class and pass in the method. I was more thinking of the kind of thing I mentioned in my earlier comment, where you have an IWriter interface, a bunch of different classes that implement it, and a Factory class that passes back the correct one for different situations. I completely agree that a whole class that does nothing but call "new" is complete overkill, and almost certainly just there to fit into a pattern because someone thinks that Patterns Are Awesome. The kind of thing I'm thinking of is this: https://github.com/andrewducker/FeedThisToThat/blob/master/FeedThisToThat/src/feedthistothat/Writers/WriterFactory.java https://github.com/andrewducker/FeedThisToThat/blob/master/F...