A factory encapsulates the logic used to create an instance, so callers do not need to repeat that logic. When several classes implement the same interface, a factory can select a concrete class, initialize an instance and return it through that interface. The calling code can then use the instance without invoking the concrete class’s constructor itself.
Two related designs are commonly called a factory. A simple factory selects an implementation in one method, often from an argument. The Factory Method pattern puts the creation operation in a superclass and lets subclasses override it to supply the product. The difference is where the creation decision belongs, not whether a method happens to be named create().
1. How the Factory Pattern Works
When an application supports several implementations of an interface, the code using an instance may not need to know which implementation was constructed. A factory separates that usage from the selection and initialization of the concrete class. The returned instance is called the product, and its interface defines the operations the caller can use.
In Factory Method, a creator class contains a workflow that needs a product. Instead of constructing one concrete class directly, the creator calls a creation method. A concrete creator subclass overrides that method and returns the appropriate product. The inherited workflow continues using the common product interface.
The participants have distinct responsibilities:
| Participant | Responsibility |
|---|---|
| Client | Selects a creator and invokes its operation. |
| Creator | Defines the workflow and declares the factory method it calls. |
| Concrete creator | Overrides the factory method to supply a particular product. |
| Product | Defines the interface used by the creator’s workflow. |
| Concrete product | Implements the behavior required by the product interface. |
A simple factory uses a different arrangement. It puts selection in a method that examines an argument and returns the matching product. There is no creator subclass overriding the creation operation. A central selection method is a simple factory; Factory Method delegates product creation through an overridable instance method.
2. Factory Pattern in Action
Consider a content editor that previews a short announcement in two formats. A plain-text preview retains the entered characters. An HTML preview places the same text inside a paragraph and represents special characters as character references so they appear as text rather than markup.
The rest of the application needs a rendering operation, but it should not repeat the format-to-class selection in every place that displays a preview. Our Renderer interface provides that operation through render(). PlainTextRenderer and HtmlRenderer implement the two formats. The products in this example are renderer instances; the strings they return are the rendered results.
With a simple factory, the application selects HTML like this:
Renderer renderer = RendererFactory.create(PreviewFormat.HTML);
String result = renderer.render("Sale <today> & tomorrow");
System.out.println(result);
The result is an HTML paragraph:
<p>Sale <today> & tomorrow</p>
RendererFactory creates the renderer; it does not render the message itself. The client calls render() on the returned instance. Changing the requested format changes the concrete renderer, while the code calling render() stays the same.
For the Factory Method version, the editor also has a shared preview workflow: reject missing or blank content, obtain a renderer, and render the message. PreviewService owns that workflow. TextPreviewService and HtmlPreviewService override its creation method to supply the renderer they need. FactoryDemo is the client for both implementations.
3. Factory Pattern Implementations
Both implementations use the same renderer interface and concrete renderers. The choice depends on whether the application needs central selection or an extensible creator workflow:
| Implementation | Choose it when | Cost of adding a format |
|---|---|---|
| Simple factory | Several callers need the same format-to-renderer selection. | Add a product, an enumeration constant and a selection branch. |
| Factory Method | Subclasses need to supply products to an inherited workflow. | Add a product and a creator subclass; configure callers to use that creator. |
The source uses JDK 17 or later. Each public type below is saved in its own file. The repository files include the package declaration; these excerpts omit that declaration.
3.1. Defining the Product Interface and Implementations
The caller needs one operation that accepts announcement text and returns a representation of it. This contract belongs in Renderer, without exposing a particular format:
public interface Renderer {
String render(String text);
}
The plain-text renderer returns the supplied text unchanged. It uses Objects.requireNonNull() to reject a missing argument:
import java.util.Objects;
public final class PlainTextRenderer implements Renderer {
@Override
public String render(String text) {
return Objects.requireNonNull(text, "text is required");
}
}
The HTML renderer uses the same method signature but produces an HTML paragraph. It first replaces ampersands, then angle brackets:
import java.util.Objects;
public final class HtmlRenderer implements Renderer {
@Override
public String render(String text) {
Objects.requireNonNull(text, "text is required");
String escaped = text.replace("&", "&")
.replace("<", "<")
.replace(">", ">");
return "<p>" + escaped + "</p>";
}
}
The replacement order matters. Converting ampersands first prevents the later replacements from having their own ampersands escaped again. For example, an input less-than sign becomes <, rather than &lt;. Java’s String.replace() replaces literal sequences here; these calls do not use regular expressions.
This renderer accepts plain text for an HTML paragraph’s text content. It is not an HTML sanitizer or an encoder for attribute values, scripts or other contexts. Those contexts require their own rules, as described in the OWASP output-encoding guidance. The factory can select a renderer, but it does not make an incorrect renderer implementation safe.
3.2. Selecting a Product With a Simple Factory
A small, fixed set of formats can be represented by an enum. Callers use an enumeration constant instead of an arbitrary string:
public enum PreviewFormat {
TEXT, HTML
}
RendererFactory.create() accepts that value and selects a concrete renderer. Its constructor is private because callers use the static creation method without constructing a factory instance:
import java.util.Objects;
public final class RendererFactory {
private RendererFactory() { }
public static Renderer create(PreviewFormat format) {
Objects.requireNonNull(format, "format is required");
return switch (format) {
case TEXT -> new PlainTextRenderer();
case HTML -> new HtmlRenderer();
};
}
}
The switch expression returns a renderer from each branch. The create() method returns Renderer, so calling code can use either result through the same interface.
Both constants are covered, so this switch expression needs no default branch. Adding an enumeration constant without adding a matching branch causes a compilation error when the factory is recompiled. The explicit null check gives a missing choice a clear error message before selection begins.
To compare the formats, pass the same message to each result:
String message = "Sale <today> & tomorrow";
for (PreviewFormat format : PreviewFormat.values()) {
Renderer renderer = RendererFactory.create(format);
System.out.println(format + ": " + renderer.render(message));
}
The two products produce different representations:
TEXT: Sale <today> & tomorrow
HTML: <p>Sale <today> & tomorrow</p>
Each call to create() runs one constructor and returns the new instance. The loop does not call either concrete renderer’s constructor. However, a new format still requires a change to this factory’s selection logic. The factory centralizes that decision; it does not remove it.
3.3. Supplying Products With Factory Method
Factory Method is useful when creation varies inside a workflow that subclasses share. Our PreviewService.preview() checks the input and then needs a renderer. The service declares createRenderer() as abstract, so a concrete service must provide the creation behavior:
import java.util.Objects;
public abstract class PreviewService {
public final String preview(String text) {
Objects.requireNonNull(text, "text is required");
if (text.isBlank()) {
throw new IllegalArgumentException("text must not be blank");
}
Renderer renderer = createRenderer();
return renderer.render(text);
}
protected abstract Renderer createRenderer();
}
The preview() method is final: subclasses inherit its validation and rendering sequence without overriding it. The factory method is protected, making it available to subclasses while keeping it outside the public preview API. Code in the same package can also access a protected method. Its declared return type is still Renderer.
The concrete services choose their products by overriding the creation method:
public final class TextPreviewService extends PreviewService {
@Override
protected Renderer createRenderer() {
return new PlainTextRenderer();
}
}
public final class HtmlPreviewService extends PreviewService {
@Override
protected Renderer createRenderer() {
return new HtmlRenderer();
}
}
The client chooses a service and calls its inherited workflow. The following calls use the same message value declared in the simple-factory example:
PreviewService textService = new TextPreviewService();
PreviewService htmlService = new HtmlPreviewService();
System.out.println("Text service: " + textService.preview(message));
System.out.println("HTML service: " + htmlService.preview(message));
The results match the corresponding simple-factory renderers:
Text service: Sale <today> & tomorrow
HTML service: <p>Sale <today> & tomorrow</p>
When htmlService.preview() runs, the inherited method checks the text and invokes createRenderer(). Java dispatches that call to the override in HtmlPreviewService, which returns an HtmlRenderer. The inherited workflow calls render() on the product supplied by the subclass and returns the resulting string.
The shared method contains no format selection and no concrete renderer constructor. A new creator subclass can supply another renderer without changing that method. This flexibility adds a creator hierarchy alongside the product types, so the simple factory is usually easier when all the application needs is a small central selection rule.
4. Running and Checking the Example
The complete FactoryDemo runs both implementations with the same announcement. It then checks instance identity and two invalid inputs. From the repository root, compile the source directory and run the entry point:
javac -d out src/main/java/com/howtodoinjava/patterns/creative/factory/*.java
java -cp out com.howtodoinjava.patterns.creative.factory.FactoryDemo
The first four lines are the format and service outputs shown above. The remaining checks show whether repeated requests reuse an instance and where invalid inputs are rejected.
4.1. Checking Repeated Requests
Requesting an HTML renderer twice produces two references. Compare them directly to check whether this factory creates separate instances:
Renderer first = RendererFactory.create(PreviewFormat.HTML);
Renderer second = RendererFactory.create(PreviewFormat.HTML);
System.out.println("Different renderers: " + (first != second));
The result is:
Different renderers: true
This follows from the new HtmlRenderer() expression in the factory. A factory could instead reuse a suitable instance, but that would be a different lifecycle policy. The pattern itself does not require either a new instance or a cached instance on every call.
4.2. Rejecting Missing Choices and Blank Content
A missing format is rejected by the simple factory. Blank content is rejected by the service’s shared workflow. The demo catches each exception so the remaining checks can still run:
try {
RendererFactory.create(null);
} catch (NullPointerException exception) {
System.out.println("Missing format: " + exception.getMessage());
}
try {
htmlService.preview(" ");
} catch (IllegalArgumentException exception) {
System.out.println("Blank preview: " + exception.getMessage());
}
The output identifies the failed requirement:
Missing format: format is required
Blank preview: text must not be blank
Objects.requireNonNull() throws the first exception before the switch runs. In the second case, preview() rejects the content before calling createRenderer(), so that request creates no renderer. Direct renderer calls accept blank text that is not null; the rule against blank previews belongs to PreviewService.
5. Extending the Design and Choosing Alternatives
Adding another format changes different code in the two implementations. With the simple factory, add a renderer implementation, a PreviewFormat constant and a matching branch. With Factory Method, add the renderer and a service subclass that returns it. The existing PreviewService.preview() workflow can remain unchanged.
Factory Method moves product creation into subclasses; application setup still chooses which creator to use. A configuration option, command-line argument or dependency-injection setup can make that choice. For example, adding another preview service leaves the shared workflow unchanged, but application setup still needs to select that service when the new format is requested.
Other creation approaches address different needs:
| Approach | Main purpose |
|---|---|
| Direct constructor | Create a known concrete class when selection and setup are already simple. |
| Abstract Factory | Supply a family of related products, such as matching controls for one UI theme. |
| Builder | Collect construction options or steps before returning a configured result. |
| Dependency injection | Supply a class with the collaborators it needs, instead of making that class find or construct them. |
Dependency injection and factories can coexist. An application can inject a factory when a component needs to create products later. If it needs only one already-configured renderer, supplying that renderer directly may be enough; adding a factory would introduce another type without solving a creation problem.
6. Frequently Asked Questions
The word factory also appears in ordinary Java API design. Distinguishing that usage from the Factory Method pattern helps avoid imposing unnecessary inheritance or lifecycle assumptions.
6.1. Is Every static Creation Method Factory Method?
No. A static factory method is a method called on a class that returns an instance. For example, LocalDate.of() returns a date for the supplied year, month and day. It does not demonstrate subclass-controlled creation. Java static methods can be hidden rather than overridden, while the Factory Method example relies on an overridden instance method.
6.2. Should a Factory Return null for an Unsupported Request?
It can, but callers must then handle the absence before using the result. An explicit exception is often clearer when the request is invalid. Our PreviewFormat type restricts callers to the declared constants; a missing value is rejected immediately. If an external API accepts format names as strings, validate and convert those names at that boundary, and give unsupported names a deliberate error response.
6.3. When Is a Factory Unnecessary?
A direct constructor is usually clearer when the caller knows the required class and construction involves no shared selection or setup. A factory is useful when it owns a creation decision that would otherwise be repeated, or when a creator workflow needs an overridable product-creation step. Moving every new expression into another class does not automatically improve the design.
7. Conclusion
Use a simple factory to centralize a shared selection rule. Use Factory Method when subclasses need to supply products to an inherited workflow. In either case, keep the product contract clear and make invalid-input and instance-reuse behavior explicit so callers know what the creation operation guarantees.
Happy Learning!
The complete example is available in the GitHub source folder.
in factory pattern.
If we have 1 laks sub classes ,then how to create factory.
if else condition,we cant put in factory class for 1 laks subclassess.
Please explain.
:-) Very hypothetical usecase. I will pass it to others.
Can you put here name for those 1 L classes?
We can use Reflection but it is costly and usecase specified by you doesn’t make sense either.
Anyway below is the partial code snipet.
1. Modify CarType enum to include classname as well.
Like for SMALL –> SmallCar etc.
public enum CarType{ SMALL("SmallCar"); private String className; public String getClassName(){return className;} public void setClassName(String className){this.className = className;} private CarType(String className){this.className = className;} } 2. You can iterate over CarType enum. public static Car buildCar(CarType model) { Car car = null; for(CarType carType : CarType.values) { if(model.equals(carType)) { car = Class.forName(carType.getClassName()).getConstructor().newInstance(); break; } } if(null == car){ // throw some exception } return car; }If you have 1 lakh subclasses, I think the next step should be to sit down and rethink your design and application domain model !
What if we need to add another car type as SUV then we need to change CarFactory which is not good practice as it voilates Open close principle.am i correct?
Adding a new CarType should not violate Open Close principle as we are not modifying any functionality of factory class by adding logic to create instance for SUV.
It works as it was working earlier.
Hi Shivan, Yes you are correct, but CarFactory class changes if we add new car type, So CarFactory class violate OCP,
Instead of if else or for loop, We can create separate factory for each car type and let client decide to choose.
Please share your though on this. Thanks
“Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.”
In case of you adding another if -else/ switch case, you are sort of extending the functionality of providing with another type of object but somewhat of the same type (thanks to abstract class/interface).But you are not modifying it.
I build a factory today to produce different kinds of chips, package and sell them. I start with potato chips and then EXTEND to produce banana chips. I am extending my functionality, not modifying the behaviour, I AM STILL A CHIPS FACTORY.
In case you have a library which today provides you with 3 Types of objects, – CAR, if you want to modify it and also provide with a ELECTRIC CAR, you have to recompile and provide the new upgraded jars. But you are still providing cars.
If you completely change/modify the behaviour it will be a problem. I think this is what OCP means. PLease pitch in in case it is wrong. Thanks
Really nice post for Design Pattern begginers
Definitely, if it’s “modern” or “up-to-date” to instantiate classes in Java within a switch case statement, you need to change your programming language right now. Consider moving your skills to a professional programming language. You are working very hard in Java. A real software development don’t need to be very hard. Regards.
Hi Fabian, Thanks for the suggestion but perhaps it will be unnecessary. I really looked up in outer world to find if I am THE alien, but found plenty of guys like this.
I will not say that you are incorrect, but will appreciate if you can express your thoughts with facts/reasons. OR you can suggest your edit in wikipedia page because there I could see the same thing.
Hi Lokesh,
How do you avoid casting after getting back an instance?
LuxuryCar lc= (LuxyryCar) FactoryManager.buildCar(CarType.LUXURY);
He overrides the “construct” method, so he doesn’t need casting ;-).
Informative post.
Regards,
Michał
Thanks a lot!
Hello Lokesh Gupta,
can you tell me how the factory method is use to save the memory in java?
Please tell me about this.
I might sound silly , why the concrete classes (Sedan,etc) are public. Since we are exposing a factory class to create us instance , it doesn’t make sense to have them public right , any one can create new instance of these classes directly from anywhere, ain’t they ??
Just what i was thinking, thanks for leaving a comment.
Hi in the original GOF factory pattern, there is a concept of having a creator and a concrete creator. I find this missing in your example. The CarFactory class is of course the concrete creator , but it does not extend from an abstract class / interface (creator)
So is it OK to call it a factory pattern without having the creator / concrete creator
It’s impossible to read this article on Samsung Galaxy 10.1 – the black advert strip jumps to the center of the webpage and covers the article text.
I am trying to understand the problem. In the mean time, if possible then can you please share a screenshot of the problem.
How to reuse the same object? i.e If we call – CarFactory.buildCar(CarType.SMALL) multiple times, it returns a new object for every call.
Regards,
Praveen Das
Hi Praveen, another question in response to your question. Why would a factory will return the same instance on each request? What’s use of this approach? I believe you will have a good reason for it, so please share with us. It will expand our thought process as well.
To answer your question, you can apply singleton pattern on different Car objects and return from construct() method.
On another thought, you should better using prototype pattern, if you want to save some CPU cycles in car construction process. Singleton simply doesn’t make sense to me.
https://howtodoinjava.com/design-patterns/creational/prototype-design-pattern-in-java/
Hi Lokesh, I’m looking at implementing a mailbox which fetches messages at a specific time interval.
Each messages fall under different types of validations, so depending on the NotificationType i call the ValidationFactory.
since there are for ex:22 notifications, and 100 messages, the notifications can be of same type. in this case i should be able to reuse the already created object for that particular NotificationType.
NotificationType would be my enum class.
ValidationService would be the parent class for all validation instances.
ValidationFactory would get me the respective object for the notificationType as input.
Regards,
Praveen
I don’t think that Factory is the pattern you are looking for. However if you really want to use Factory pattern as your approach you should combine it with a caching adapter for the actual Factory which returns the cached instances.
Thanks for this wonderful example. My doubt is why do I get a warning in my IDE that the method “construct()” shouldn’t be called in side the construtor because it’s an overridable method?
I read that it has something to do with inheritance and if other classes extend this class things COULD go wrong down the line if someone overrides that method in another place.
Did I understand correctly the potencial danger here?
There is a danger in doing this and you should not do it (add overridable methods in the constructor)
Effective Java 2nd Edition, Item 17: Design and document for inheritance or else prohibit it
“There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will get invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.”
Pretty valid point.
Agreed!
Thanks Lokesh Gupta ji.
I guess there is one small mistake (inaccuracy) in your example.
You have to make method constcut() abstract and put it into constructor instead of method arrangeParts():
public Car(CarType model) {
this.model = model;
//arrangeParts(); // remove this. You cold leave it but it just misslead you, it has nothing to design pattern.
construct(); // abstrac method! will be called implementation from interited class.
}
Then constructor LuxuryCar will look like:
LuxuryCar() {
super(CarType.LUXURY);
//construct(); // remove this!
}
Agreed!
dear roman , pls explain i am new to java you told that use construct method in Car class constructor if we do so than how it will display information, because constructor will use this method definition from its own class and in Car class method construct() have empty definition that it is abstract.
Sagar, Car is an abstract class you cannot create instance of it. You can create instance of classes which “extend Car” e.g. SmallCar. So actually in runtime construct method will be called either from SmallCar, SedanCar or LuxuryCar only. At this stage I would like to suggest you to first brush up the basic java concepts. That will help you in understanding more complex topics. Good Luck !!
thnx
Can you pls suggest me learning link with exercise.
https://docs.oracle.com/javase/tutorial/java/index.html
https://docs.oracle.com/javase/tutorial/collections/index.html
And Then
https://howtodoinjava.com/java/
thnx boss :)
I do not agree with you Roman. The example is great.
The consruct() method is for logical code in the inherited Sub-Classes,
while method arrangeParts() is calling in the constructor, if in some cases has needs for that.
Regards
Good post, thank you. Could you make it a bit more complex (as part2) in the way, lets say: Car is composed of underframe, engine and body and each of this component is created by factory depending of type of a car. What I’d like to see is how those factories will be used together, where to put it, how to call it. Thanks
A similar study you will find at: https://howtodoinjava.com/design-patterns/creational/abstract-factory-pattern-in-java/
Ok, thanks. What I’m trying to achieve is how to junittest class which have nested classes which have nested classes. Lets say: Service class uses nested Util class and Util class uses nested library class. And that library class is created by hardcoded new LibClass() but I’d like to use factory to easily switch instance to LibTestClass(). That is because LibClass connects to the internet but I’d like to mock it. By factory. Not by EasyMock or so even if it is possible. Lets say in another production environment I’d like to use LibClassDatabase() instead of LibClassHttp()
Awesome stuff! Thanks.
Read jus now before interview…really worth it!
You did not mention where CarFactory.buildCar() should be called… You have just written the testing part but I suppose the integration part is missed…
Whenever you want a instance of car, use this method. Integration part.. I don’t fully understand what you are referring to?? Where you want to integrate this example??
Thanks for ur prompt response… I got it… 1 more ques… In the UML diagram, am not able to understand the relationship between Car and CarFactory…
yeah the arrow shud be in opposite direction.
i do agree , the arrow should be in opposte direction
Ref : see uml diagram in : https://en.wikipedia.org/wiki/Factory_method_pattern