
Imagine you are building the trading desk at a brokerage like Zerodha or Robinhood. Users search for a stock symbol and expect to buy or sell within seconds. Behind that search box there are dozens of instrument types: Apple equity, Amazon equity, Google equity, and tomorrow Microsoft, Tesla, and an ETF family. If every service that handles an order writes its own if (symbol.equals("AAPL")) return new AppleStock() branching, you will have copy-pasted creation logic in the order router, the risk engine, the portfolio renderer, and every test. Add one instrument and you touch five places. Miss one and production routes an Apple order through a generic fallback that lacks exchange-specific rules.
The Factory design pattern in Java solves exactly this centralized-creation problem. It moves all of that branching into one factory that decides which concrete stock implementation to create, while clients program only against the Stock abstraction. You ask for a stock by a business key, the factory decides the class, and the rest of the system never learns the concrete type. This guide expands the pattern from definition to production trade-offs, and if you want the subclass-driven variant that follows naturally, read Factory Method Pattern in Java: Explanation and Example next.
Table of Contents
Open Table of Contents
- What Is the Factory Pattern?
- Why Factory Exists: The Creation Problem
- Factory vs Direct new vs Factory Method vs Abstract Factory
- Participants and Their Responsibilities
- Mermaid Creation Flow Diagram
- Implementation Steps
- Real-World Code Example: Stock Exchange Factory
- Real-World Example: How JDK, Spring, and Uber Use Factory
- When to Use vs When NOT to Use
- Advantages and Trade-offs
- Common Pitfalls
- Interview Questions
- 1. What is the Factory pattern and what concrete problem does it remove?
- 2. How is Simple Factory different from Factory Method in practice?
- 3. Why should a factory return the abstract type instead of the concrete product?
- 4. Why is enum preferred over String as the factory discriminator?
- 5. What is the usual error policy for unknown factory inputs and why not return null?
- 6. When would you evolve a Simple Factory into Abstract Factory or Builder?
- Conclusion
- References
- YouTube Videos
What Is the Factory Pattern?
Factory is a creational pattern that encapsulates object creation behind a dedicated method or class, so clients request products by an abstraction rather than calling constructors directly. You can think of it as a single registry window at the exchange: the trader hands over a ticker symbol, the window hands back a handle that supports buyShares() and sellShares(), and the trader never asks whether the handle was built from an AppleStock or a GoogleStock constructor.
This pattern is sometimes called Simple Factory and is not one of the original 23 GoF patterns, yet it is the foundation every GoF creational pattern builds upon. The core guarantee is decoupling. The client depends on Stock and on StockFactory, not on every concrete stock class. That decoupling is what lets you change how an AppleStock is configured, where its market data comes from, or whether it validates share counts differently, without touching a single call site outside the factory.
The distinction that trips most beginners is terminology. When your factory is a single class with a method like getStock(StockCompany company) that switches on an enum or string, you are using Simple Factory. When that method is declared abstract and subclasses override it, you have evolved into Factory Method Pattern in Java: Explanation and Example. When the factory must create coherent families of products such as processor plus storage that must match, you have graduated to Abstract Factory Pattern in Java: Explanation and Example. Naming the level you are at helps code review stay honest about complexity.
Why Factory Exists: The Creation Problem
Most real systems create objects whose concrete type depends on runtime data. Consider how Swiggy routes a payment instruction. The user pays with UPI, card, or wallet, and each instrument needs a different gateway client, validation, and settlement adapter. If every service builds the gateway with scattered if-else chains, two problems compound. First, the product hierarchy is duplicated, which means a change to how a gateway is constructed must be replicated across services. Second, clients become coupled to concrete types, so a test that should run with a fake gateway must instead mock a concrete constructor that is spread across ten places.
Factory addresses this by making the creation decision a first-class responsibility owned by one place. The factory method owns the switch, owns the knowledge of which constructor arguments each product needs, and owns the error policy for unknown inputs. The client owns business logic that uses the product through its abstract type. The contrast with sprinkling new operators everywhere is not cosmetic. It is the difference between paying the complexity cost once at the factory boundary and paying it every time someone writes a new service, which is also why dependency management guidance in SOLID Principles in Java frames creation coupling as a design risk rather than boilerplate preference.
The naive alternative that teams try first is a static helper with magic strings. createStock("APPLE") compiles, passes a string around, and fails at runtime when someone types "apple" or "AAPL " with a trailing space. Replacing the string with StockCompany enum in the factory signature turns that runtime mismatch into a compile-time signal and, more importantly, gives the IDE the list of valid families. That shift from stringly-typed branching to typed factory methods is a small move that quietly prevents a whole class of production incidents.
Factory vs Direct new vs Factory Method vs Abstract Factory
Four options cover most creation scenarios and mixing them up is a frequent source of over-engineering:
Direct new: The client knows the exact class. Use it when the type never varies and construction has no branching. A value object like Money constructed with an amount and a currency does not need a factory.
Simple Factory: A single factory method decides among siblings of one product hierarchy based on a parameter. Use it when you have one product axis that varies at runtime. The stock exchange example is exactly this: one hierarchy, Stock, parameterized by company.
Factory Method: Creation is defined as an abstract method and subclasses decide the variant through inheritance. Use it when the decision to create belongs to a framework and you want subclasses to plug in the specific type without editing the base, which the companion post Factory Method Pattern in Java: Explanation and Example covers in depth.
Abstract Factory: Multiple related products must be created together as a family and stay consistent. Use it when you need a button plus checkbox that share a theme, or a processor plus storage that share a vendor. When there is only one product, Abstract Factory is premature.
Choose the lightest option whose guarantee you actually need. If the failure mode is a missing case branch for one product, Simple Factory is sufficient. If the failure mode is new AppleProcessor() accidentally paired with DellStorage, the family guarantee of Abstract Factory is the correct remedy.
Participants and Their Responsibilities
Simple Factory has four participants, and each one earns its place by owning a clear piece of lifecycle:
Product abstraction is the Stock abstract class or interface that defines what the client can rely on, such as buyShares(int n) and sellShares(int n). WHY abstract? Because the client must not acquire the freedom to call Apple-only behavior after creation. A narrow contract guarantees that any future instrument that honors buying and selling semantics can substitute without client edits.
Concrete products such as AppleStock, AmazonStock, and GoogleStock implement that contract with business-specific side effects. WHY keep them separate instead of one parameterized GenericStock? So that exchange-specific rules, logging, or validations can diverge. An ETF product and an equity product will eventually differ in settlement handling, and a single generic class with flags would accumulate conditionals again.
Factory is the StockFactory that exposes getStock(StockCompany company) and owns the branching. WHY return Stock rather than a concrete type? To preserve substitution. Returning a concrete type would let callers downcast and couple to it. Returning the abstraction communicates what the client is allowed to depend on.
Client is any caller such as Client.main() that invokes the factory and uses the product through its abstraction. WHY should clients never name concrete stock classes? Because naming reintroduces the coupling the factory exists to remove. A client that calls new AppleStock() directly bypasses centralized validation, exchange info, and the error boundary for unknown instruments.
The enum StockCompany is a small but important design partner. Using it as the factory parameter instead of String narrows the domain at the type level, makes unknown-value handling explicit through a default throw, and lets search and refactoring track every creation site through a single enum rather than a fragile string search.
Mermaid Creation Flow Diagram
flowchart TD
C[Client\nrequests Stock] --> F[Factory\nStockFactory.getStock]
F --> S{StockCompany?}
S -- APPLE --> A[Concrete Product\nAppleStock]
S -- AMAZON --> AM[Concrete Product\nAmazonStock]
S -- GOOGLE --> G[Concrete Product\nGoogleStock]
S -- Unknown --> ERR[Throw IllegalArgumentException]
A --> P[Abstract Product\nStock]
AM --> P
G --> P
P --> U[Client uses\nbuyShares / sellShares]
U --> EX[exchangeInfo\nexecuted inside factory]
EX --> RET[Return Stock\nto Client]
RET --> NF{New Company?\ne.g. MICROSOFT, TESLA}
NF -- Yes --> F
NF -- No --> DONE[End]
classDef factory fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:#000000;
classDef product fill:#f3e5f5,stroke:#4a148c,stroke-width:2px,color:#000000;
classDef client fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px,color:#000000;
class F,ERR factory;
class A,AM,G,P,EX product;
class C,U,RET,NF,DONE client;
The loop that matters is at the bottom. Adding a new instrument such as Microsoft or Tesla loops back into StockFactory.getStock() as one more branch plus one new concrete product, while clients like Client.main() remain unchanged beyond the enum value they pass. That locality is the practical meaning of the Open-Closed Principle for Simple Factory and a direct application of the cohesion and abstraction guidance in SOLID Principles in Java.
Implementation Steps
A clean Simple Factory implementation follows four steps, each with a practical check that prevents the usual regression:
-
Define the product abstraction first. Declare
StockwithbuyShares()andsellShares()plus any common helper likeexchangeInfo(). WHY start here? Because the public contract is the blast radius. If the interface leaksgetAppleDividendCalendar(), every factory consumer is polluted with Apple semantics and swapping instruments breaks. -
Implement one concrete product per variant. Create
AppleStock,AmazonStock, andGoogleStockthat override the abstract methods. Keep logging and validation local to each product so that the behavior of one instrument can change without touching siblings. -
Replace scattered construction with a typed factory method. Implement
StockFactory.getStock(StockCompany company)with aswitchthat returnsStock. Use the enum, throw on unknown values rather than returning null, and keep auxiliary behavior likeexchangeInfo()inside the factory so every product shares the base setup without clients remembering to call it. -
Rewrite clients to depend only on abstractions. Replace every call site that previously did
new AppleStock()withfactory.getStock(StockCompany.APPLE)and program againstStock. Verify that no client imports a concrete product after the migration. If a client still compiles when concreteAppleStockis deleted, the abstraction has succeeded. For object families that later require multiple coordinated products, revisit the family approach in Abstract Factory Pattern in Java: Explanation and Example, and for construction that needs many optional fields, compare with Builder Pattern in Java: Explanation and Example.
Real-World Code Example: Stock Exchange Factory
The scenario is a NASDAQ trading client that must route buy and sell requests for multiple listed companies through one entry point. The client supplies a StockCompany and receives a ready-to-use Stock handle. Every handle announces the exchange and then executes the domain action.
Product Abstraction
This is the narrow contract clients are allowed to rely on.
package com.adevguide.java.designpatterns.factory;
// WHY: abstract product hides concrete instrument details so client can swap companies without changing call sites
public abstract class Stock {
public abstract void buyShares(int n);
public abstract void sellShares(int n);
// WHY: common behavior lives in the abstraction so factory can enforce it uniformly before return
public void exchangeInfo() {
System.out.println("You are making Transactions at NASDAQ");
}
}
Concrete Products
Three variants illustrate sibling substitution. The implementation logic is intentionally small, but each product remains the natural place for future divergence such as lot-size validation or fee schedules.
package com.adevguide.java.designpatterns.factory;
public class AppleStock extends Stock {
@Override
public void buyShares(int n) {
// WHY: product owns instrument-specific messaging so factory and client stay generic
System.out.println("Congrats!! You have successfully bought " + n + " Apple Shares.");
}
@Override
public void sellShares(int n) {
System.out.println("Congrats!! You have successfully sold " + n + " Apple Shares.");
}
}
package com.adevguide.java.designpatterns.factory;
public class AmazonStock extends Stock {
@Override
public void buyShares(int n) {
System.out.println("Congrats!! You have successfully bought " + n + " Amazon Shares.");
}
@Override
public void sellShares(int n) {
System.out.println("Congrats!! You have successfully sold " + n + " Amazon Shares.");
}
}
package com.adevguide.java.designpatterns.factory;
public class GoogleStock extends Stock {
@Override
public void buyShares(int n) {
System.out.println("Congrats!! You have successfully bought " + n + " Google Shares.");
}
@Override
public void sellShares(int n) {
System.out.println("Congrats!! You have successfully sold " + n + " Google Shares.");
}
}
Enum for Type-Safe Selection
package com.adevguide.java.designpatterns.factory;
// WHY: enum parameter turns runtime string typos into compile-time completeness and searchable usages
public enum StockCompany {
APPLE,
GOOGLE,
AMAZON,
MICROSOFT;
}
Factory That Owns Creation
package com.adevguide.java.designpatterns.factory;
public class StockFactory {
// WHY: return Stock abstraction so callers cannot depend on AppleStock directly
public Stock getStock(StockCompany company) {
Stock stock;
switch (company) {
case APPLE:
stock = new AppleStock();
break;
case GOOGLE:
stock = new GoogleStock();
break;
case AMAZON:
stock = new AmazonStock();
break;
default:
// WHY: fail fast with IllegalArgumentException rather than returning null that causes NPE downstream
throw new IllegalArgumentException("The stock is not listed in the market yet.");
}
// WHY: common initialization stays in factory so clients cannot forget it
stock.exchangeInfo();
return stock;
}
}
Client That Depends Only on Abstractions
package com.adevguide.java.designpatterns.factory;
public class Client {
public static void main(String[] args) {
try {
// WHY: instantiate factory once and reuse; factory is cheap and stateless here
StockFactory stockFactory = new StockFactory();
Stock appleStock = stockFactory.getStock(StockCompany.APPLE);
appleStock.buyShares(10);
System.out.println("**********************************");
Stock amazonStock = stockFactory.getStock(StockCompany.AMAZON);
amazonStock.sellShares(20);
System.out.println("**********************************");
// WHY: Microsoft is not yet wired in factory, so this demonstrates the default error policy
Stock microsoftStock = stockFactory.getStock(StockCompany.MICROSOFT);
microsoftStock.buyShares(10);
} catch (Exception e) {
// WHY: production would map IllegalArgumentException to a domain error response, not print stack trace to stdout
e.printStackTrace();
}
}
}
Output:
You are making Transactions at NASDAQ
Congrats!! You have successfully bought 10 Apple Shares.
**********************************
You are making Transactions at NASDAQ
Congrats!! You have successfully sold 20 Amazon Shares.
**********************************
java.lang.IllegalArgumentException: The stock is not listed in the market yet.
at com.adevguide.java.designpatterns.factory.StockFactory.getStock(StockFactory.java:24)
at com.adevguide.java.designpatterns.factory.Client.main(Client.java:22)
Notice what did not appear in the client: no branching on symbol strings, no concrete constructor import, and no duplicated exchange announcement. That absence is the point. The decision logic lives in exactly one place, and every call site shares the same entry ceremony and the same failure signal.
Real-World Example: How JDK, Spring, and Uber Use Factory
JDK Calendar, NumberFormat, and valueOf(). Calendar.getInstance() does not call new GregorianCalendar() in client code. It inspects locale and timezone, then returns the correct Calendar subtype. NumberFormat.getInstance() and ResourceBundle.getBundle() do the same per locale. Wrapper methods like Integer.valueOf(int) and Boolean.valueOf(String) add caching semantics. Integer.valueOf() reuses instances for [-128, 127] rather than allocating, which is why performance guides warn against new Integer() and why factory ownership of construction lets the platform introduce caching without client edits.
Spring BeanFactory and FactoryBean. Spring’s BeanFactory.getBean("paymentGateway") is a managed factory that decides which concrete bean to construct based on profile, scope, and conditional configuration. A FactoryBean further hides construction that needs resource lookups, proxy creation, or lifecycle hooks. Teams that introduce a second payment provider on Black Friday do not hunt down constructors. They add a new bean definition, and the central factory selects it via configuration.
Uber and brokerage order routing in production. Large marketplaces that handle heterogeneous fulfillment flows, from Uber matching rider requests to different vehicle services to a brokerage routing equities versus options, typically front domain services with a typed factory such as PaymentGatewayFactory.forMethod(method) or InstrumentFactory.forSymbol(symbol). The factory owns provider-specific validation and logging decoration, which keeps risk and settlement logic from drifting into UI layers. The lesson from incidents in these systems is consistent: scattered creation logic is where fee-calculation bugs hide, and consolidating that logic behind a factory makes audit and rate-limiting policy review tractable in one place.
When to Use vs When NOT to Use
Use Factory when:
-
Product type varies at runtime based on input data and clients should not name concrete classes. A payment gateway selected by method or a notification channel selected by user preference is the canonical trigger.
-
Creation has shared setup that every product must receive, such as exchange announcement, telemetry tagging, or default configuration. Centralizing that setup behind
exchangeInfo()is cheaper than trusting every call site to remember it. -
The product hierarchy is expected to grow in siblings but not in structure. Adding a new
TeslaStockalongside existing instruments is exactly the additive change Simple Factory handles well. The Open-Closed signal in SOLID Principles in Java applies here.
Do NOT use Factory when:
-
Creation never varies. If the service always uses one gateway, a typed factory is ceremony that doubles test setup for no swapping benefit.
-
Branching is shallow and construction is trivial with no shared setup. A plain
newor a small helper method reads more clearly than a new enum plus factory plus throw policy. -
You actually need coordinated families. If
ProcessorandStoragemust match by brand, a single-productgetStock()factory will let callers accidentally mix them. That invariant belongs to Abstract Factory Pattern in Java: Explanation and Example.
| Dimension | Use Factory | Avoid Factory |
|---|---|---|
| Product axis | One hierarchy varies by runtime input | Type is fixed and known at compile time |
| Setup | Common initialization per product | No shared setup across products |
| Extension | Add siblings frequently | Product hierarchy is stable and tiny |
| Coupling risk | Scattered new would duplicate branching | Factory adds indirection without reuse |
| Family scope | Single product per request | Related products must stay consistent as a kit |
Advantages and Trade-offs
Simple Factory gives you locality of change and decoupling from concrete types. Client tests can pass a test-double factory that returns fakes, so business logic that consumes Stock stays fast and deterministic without bringing up a market data dependency. It enforces a uniform error policy for unknown inputs, which removes the classic null return regression where callers forget to null-check and throw a NullPointerException two calls later under a rare symbol. It also turns stringly-typed branching into a typed enum at the method signature, so the compiler and IDE guide callers to valid values. Compared to ad-hoc helpers scattered across services, having one factory makes code navigation and ownership clear, because a new hire searches for StockFactory and arrives at the complete creation surface.
The price is that Simple Factory centralizes knowledge, which means every new sibling touches that central switch. In a fast-moving domain with weekly instrument additions, the factory can feel like a bottleneck file with merge contention. The mitigation is to keep the switch narrow and to promote the pattern when its limits show: either introduce a registry-backed factory where new products self-register, or graduate to Factory Method Pattern in Java: Explanation and Example where the branching is distributed across subclasses rather than accumulated in one method. The blunt alternative is not replacing factory with DI alone. A dependency injection container can choose which factory to inject, but it still benefits from the factory interface to keep the creation boundary explicit, rather than assembling concrete products piecemeal in configuration code.
Finally, the testing burden shifts, not disappears. Factories themselves deserve dedicated tests that exercise every enum branch, the default throw path, and any shared setup like exchangeInfo(). Without those, a passing client suite can mask a factory that silently constructs incomplete products or forgets validation. Budget for factory-level coverage early rather than discovering gaps after a partner symbol reaches production and takes the generic fallback path.
Common Pitfalls
Returning null for unknown inputs instead of failing fast. A factory that does default: return null looks harmless because the caller technically received a value. The next line stock.buyShares(10) then throws a NullPointerException far from the real cause, and the log points at the caller, not the factory decision. Before long, every caller adds defensive if (stock == null) checks that drift apart. Fix this by throwing IllegalArgumentException or a domain exception from the default branch and by testing that branch explicitly, so the root cause surfaces where the branching lives.
Using String instead of a typed discriminator. A signature like getStock(String company) accepts "apple", "APPLE ", and "App1e" at compile time and fails only at runtime. Refactors cannot locate all call sites by symbol search when typos produce separate string literals, and conditional downstream logic quietly introduces case-insensitive matches that hide bugs. Replace strings with StockCompany enum, and if an external API hands you a raw string, parse it once at the edge with StockCompany.valueOf(normalized) before entering the factory boundary.
Letting clients bypass the factory with direct constructors. Even a perfect StockFactory is undermined when a new feature ships new AppleStock() directly because the factory felt like overhead for a quick experiment. That experiment bypasses exchangeInfo(), bypasses validation, and slowly reintroduces scattered branching as it is copied. Prevent this drift by making concrete product constructors package-private where possible, by adding a lint or architecture rule that flags new AppleStock imports outside the factory package, and by pairing that rule with a code review checklist that requires every new product addition to land in the factory test file.
Interview Questions
1. What is the Factory pattern and what concrete problem does it remove?
Factory centralizes the decision of which sibling to instantiate so clients do not duplicate if-else creation chains. Without it, the order router, risk engine, and portfolio renderer each decide how to build an AppleStock, which means a new instrument touches many files and inconsistency creeps in. With a typed StockFactory, creation branching lives in one method that returns Stock, while callers program only against Stock. Tests then depend on the same abstraction and can inject fakes from the factory, so business logic coverage stays fast and does not depend on real market data construction.
2. How is Simple Factory different from Factory Method in practice?
Simple Factory is a single class, usually with one method that switches on an enum, and it is not part of the original GoF catalog. Factory Method is a GoF pattern where a base class declares an abstract creation method and subclasses override it to supply the concrete type. Choose Simple Factory when one axis varies by runtime input and the decision fits naturally in a local switch. Choose Factory Method when you want inheritance to decide creation and you prefer to eliminate the central switch by distributing decisions across subclasses. The companion deep dive Factory Method Pattern in Java: Explanation and Example contrasts the trade-offs with working code.
3. Why should a factory return the abstract type instead of the concrete product?
Returning Stock instead of AppleStock keeps clients from depending on behavior that only one sibling exposes. Once a method signature promises AppleStock, callers start calling Apple-only helpers, and adding a new instrument requires editing every caller to consider another branch. Returning the abstraction documents the allowed surface and preserves substitution, which is the Open-Closed expectation in SOLID Principles in Java. If a family-specific capability is genuinely needed, expose it through a query or capability interface rather than a forced cast.
4. Why is enum preferred over String as the factory discriminator?
A StockCompany enum makes only valid values constructible at compile time and lets the IDE and type system enforce completeness. A String parameter defers correctness to runtime, so a typo like "APPLE " compiles, propagates, and fails after deployment. Enums are also searchable and refactorable. Searching for StockCompany.MICROSOFT finds every creation decision, while searching for "MICROSOFT" misses case variants and concatenations. When an external boundary hands you a raw string, validate and map to the enum once, before entering the factory.
5. What is the usual error policy for unknown factory inputs and why not return null?
The standard policy is to throw IllegalArgumentException or a domain-specific UnknownInstrumentException from the factory default branch. Returning null pushes the failure to a later dereference, which produces a NullPointerException with a stack trace that points at innocent client code instead of the missing product mapping. Throwing inside the factory makes the cause explicit and lets service boundaries translate the factory exception into the correct HTTP or domain response. Factory tests should assert this throw path for every StockCompany value not yet wired.
6. When would you evolve a Simple Factory into Abstract Factory or Builder?
Evolve to Abstract Factory when a single product is no longer the invariant and the system must keep related products aligned, such as a Processor that must be paired with a compatible Storage or a payout rail that needs a matching signer plus endpoint. Keeping a single-product factory in that situation allows mismatched pairs. Evolve to Builder when the difficulty is no longer which product to create but how many optional parts to assemble into one well-formed, immutable result, for example a TradeOrder with conditional legs and identifiers. The family invariant favors Abstract Factory, while the many-optional-parts pressure favors Builder Pattern in Java: Explanation and Example.
Conclusion
Simple Factory earns its keep when many creation sites share one decision:
- Centralize branching. One factory method owns the product switch so new siblings are added in one place without scattering conditionals.
- Program against the abstraction. Clients should import
StockandStockFactory, not concrete siblings, so swapping instruments is a wiring change rather than a code hunt. - Type the discriminator. Replace strings with
StockCompanyenum to catch invalid inputs at compile time and make every creation site searchable. - Fail fast at the factory. Throw on unknown inputs instead of returning null, and keep shared setup such as
exchangeInfo()inside the factory so callers cannot forget it. - Graduate when the invariant changes. When a single product becomes a kit that must stay compatible, move to Abstract Factory, and when the challenge becomes assembling many optional parts immutably, move to builder.
The next topic in this series to continue creational design skills is Builder – assembling many optional fields immutably – which solves construction complexity of a different shape from centralized type selection. For the sibling patterns that build on this foundation, contrast with Factory Method Pattern in Java: Explanation and Example and the family-oriented Abstract Factory Pattern in Java: Explanation and Example.
References
- Factory Pattern - Refactoring Guru
https://refactoring.guru/design-patterns/factory-method - Factory Method Pattern - OODesign
https://www.oodesign.com/factory-pattern.html - Design Patterns: Elements of Reusable Object-Oriented Software - Gamma et al.
https://en.wikipedia.org/wiki/Design_Patterns
YouTube Videos
-
“The Factory Design Pattern In Java”
https://www.youtube.com/watch?v=q6xHRXI93sM -
“Factory Design Pattern in Java with Example | Java Guides”
https://www.youtube.com/watch?v=zgf8QD7n5qI -
“Factory Design Pattern in Java”
https://www.youtube.com/watch?v=jcGSowIzmzM