0

I need to vary the object creation at (*).

public class Parser { // Problem code
 public List<FileOption> methodA() {
 // Does something ... 
 fileOptions.add(new FileOptionImpl(line)); <--- (*)
 return fileOptions;
 }
}

One way is to apply the abstract factory pattern, but now that the factory only is to have a single method that returns a concrete class, is this considered overkill? If it is, what should I rather do in this situation?

private final FileOptionFactory fileOptionFac; // Problem code solved using abstract factory
public Parser(FileOptionFactory fileOption) {
 this.fileOptionFac = fileOption;
}
public static List<FileOption> methodA() {
 // Does something ...
 fileOptions.add(new fileOptionFac.createFileOption(line)):
 return fileOptions;
}
asked Dec 7, 2020 at 16:21
4
  • What is the problem with the original implementation? Commented Dec 7, 2020 at 19:20
  • @Helena That it might be overkill. But perhaps it is not? What do you think? The reason why I feel like it is overkill is because I have to define two concrete factories and one factory interface; and all the concrete factories does is have a single method that instantiates and returns a concrete class ... Sigh, but if that is my only option... ? Commented Dec 7, 2020 at 20:24
  • I was talking about the code you call "problem code" using a simple constructor. What is the problem with that code? Why do you need to vary the object creaton? Commented Dec 7, 2020 at 20:51
  • Why you need to get rid of this line in original code sample fileOptions.add(new FileOptionImpl(line))? - If FileOptionImpl doesn't have external dependencies(accessing database or file system or web services) then it totally fine to create it with the constructor, especially in your case where constructor has only one argument. Commented Jan 6, 2021 at 23:01

2 Answers 2

1

The abstract factory pattern has fallen out of favor for a number of reasons but mostly due to a general trend towards dependency injection (DI) with or without a framework.

This appears to be Java and another consideration is that with the ability to pass in a function, there tends to be very little reason to create all the definitions that you would need for an abstract factory. In addition, those definitions are almost always just noise. They don't define any functionality, they simply declare types. Here's an example of what you can do instead:

public interface FileOptionFactory {
 FileOption create(String line);
}
public class Parser {
 private final FileOptionFactory factory;
 public Parser(FileOptionFactory factory) {
 this.factory = factory;
 }
 
 public List<FileOption> methodA() {
 // Does something ...
 fileOptions.add(factory.create(line));
 return fileOptions;
 }
}

And now you can then create Parser like this:

new Parser(FileOptionImpl::new);

This, IMO, gives a pretty balance between clarity and simplicity (for Java.) If you are struggling with how to pass this parameter into the Parser constructor, you might want to consider a DI framework or refactor the code in other ways.

answered Dec 7, 2020 at 19:56
2
  • One issue with DI is that it causes a bloat of parameters in the constructor, since you now have to pass all those concrete instances by instantiation instead. This is solved by encapsulating the concrete instances using the abstract factory pattern. Thus, DI creates more instances where the abstract factory pattern is highly applicable. In the light of that, your first sentence doesn't make any sense. In my mind: DI used more => abstract factory p. used more Commented Dec 7, 2020 at 20:33
  • Not true. There are lot's of tools that allow you to use annotations to configure things. Another option is you can have a single parameter that holds references to other objects.. You seem a little bit trapped by some of your own assumptions here. Commented Dec 8, 2020 at 15:36
-1

The abstract factory pattern can be useful even if only returning one object. But if you hard code the factory by sticking a new in front of it you’re just as statically bound as a static factory method.

The real power of the abstract factory comes from it’s abstract nature. I can use an abstract factory to hide what is really making time stamps. Now sure that’s kicking out one simple class. But it’s hiding what that class is. And it’s making in on demand. And I can change which factory is making it whenever I like.

DI has not made abstract factory obsolete. It still has cases where it’s still the best choice. On demand polymorphic object construction is hard to beat when you need it.

answered Dec 7, 2020 at 21:15
6
  • It would help if you could give an example or two of where the abstract factory pattern is better than a factory object/method provided by DI and why. Commented Dec 8, 2020 at 15:58
  • @JimmyJames I did. Time stamps. DI works when you have one statically constructed object graph. However, if you have objects that must be constructed later, like time stamps, then one time construction in the composition root isn’t enough. Instead inject a factory that will construct whatever on demand. Commented Dec 8, 2020 at 16:25
  • And why isn't passing in a timestamp factory method adequate? Commented Dec 8, 2020 at 17:00
  • Are you perhaps confusing the abstract factory pattern with the factory method pattern? Commented Dec 8, 2020 at 17:27
  • Given a choice I prefer polymorphism. Commented Dec 8, 2020 at 17:32

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.