Design Patterns — Simple Factory in Angular
Creational design patterns are concerned with the way of creating objects.
In JavaScript, TypeScript, etc., the way to create an object is by using the new operator.
Creational patterns consist of:
1. Factory (Simple Factory)
2. Factory Method
3. Abstract Factory
4. Singleton
5. Prototype
6. Builder
7. Object Pool
In this article, I will explain how the Factory (Simple Factory) pattern works. You can see and run an example of the Factory (Simple Factory) pattern in a demo project, which can be found at this link here.
A Factory (Simple Factory), depending on the provided data, returns an instance of one of the possible classes. Most often, the returned classes derive from the same base class and have the same methods, but each performs its tasks in a different way. This pattern serves as an introduction to the Factory Method pattern and is a variation of it.
To create a Factory (Simple Factory) pattern, we can use a form that allows the user to input an IBAN (International Bank Account Number) starting with two characters that are letters, representing the country of the bank account number. Let’s start by defining the base class Name.
export class Name {
protected country: string = ''
protected bankAccountNumber: string = ''
getCountry() {
return this.country
}
getBankAccountNumber() {
return this.bankAccountNumber
}
}
In the above base class Name, we do not process the text. It only serves to store the country and bank account number in separate variables and provides the methods getCountry() and getBankAccountNumber() so that derived classes have access to these attributes.
Now let’s implement two classes, Country and BankAccountNumber, which are derived from the Name class. Their methods will determine the country of the bank account number based on the provided characters and separate the account number from the country code.
export class Country extends Name {
constructor() {
super()
}
getValueCuntry(value: string) {
const firstTwoChars = value.substring(0, 2);
const regex = /^[A-Za-z]{2}$/;
if (regex.test(firstTwoChars)) {
this.country = this.nameCoutry(firstTwoChars)
} else {
this.country = firstTwoChars
}
return this.country
}
nameCoutry(value: string) {
switch (value.toUpperCase()) {
case 'PL': {
return this.country = 'Poland'
}
case 'US': {
return this.country = 'United States'
}
case 'CZ': {
return this.country = 'Czech Republic'
}
default: {
return this.country = value
}
}
}
}
export class BankAccountNumber extends Name {
constructor() {
super()
}
public getValueBankAccountNumber(value: string) {
const numericChars = value.substring(2);
const digits = numericChars.match(/\d+/g);
if (digits) {
this.bankAccountNumber = numericChars
} else {
this.bankAccountNumber = value
}
return this.bankAccountNumber
}
}
The Simple Factory pattern is achieved based on a deciding class. The class makes the decision about which instance of the appropriate class should be returned.
export class NamerFactory {
checkValue(entry: string) {
const firstTwoChars = entry.substring(0, 2);
const regex = /^[A-Za-z]{2}$/;
if (regex.test(firstTwoChars)) {
const country = new Country().getValueCuntry(entry)
return country
} else {
const bankAccountNumber = new BankAccountNumber().getValueBankAccountNumber(entry)
return bankAccountNumber
}
}
}
For the purpose of this example, I have added an input field where you can enter a sample IBAN. The field includes the method (ngModelChange)=”checkBankNumber(iban = $event)” which takes the entered characters, creates an object of the deciding class NamerFactory, and then returns the country name of the bank account number:
@Component({
selector: 'app-simple-factory',
standalone: true,
imports: [FormsModule],
template: `
<p>simple factory </p>
<input [ngModel]="iban" type="text"
(ngModelChange)="checkBankNumber(iban = $event)">
<p>Country of bank account number {{ country }} for {{iban}}</p>`,
styleUrl: './simple-factory.component.scss'
})
export class SimpleFactoryComponent extends NamerFactory {
country = ''
constructor() {
super()
}
iban = ''
checkBankNumber(event: string) {
const namerFactory = new NamerFactory()
this.country = namerFactory.checkValue(event)
}
}
Summary
The idea of the Simple Factory pattern is to create an abstraction (class) that makes the decision about which class among many derived classes to return and creates its instance. We then call methods on the instance without knowing which derived class the current instance refers to. In this way, we create an interface for the class, deferring its implementation to the derived classes.
Materials:
- Java. Wzorce projektowe. Translation: Piotr Badarycz. Original title: Java design patterns. A Tutorial. Author: James William Cooper
My other articles related to Design Patterns in Angular:
Structural patterns:
Design Patterns — Proxy in Angular
Design Patterns — Composite in Angular
Design Patterns — Adapter in Angular
Design Patterns — Decorator in Angular
Creational patterns:
Design Patterns — Builder in Angular
Behavioral patterns:
Design Patterns — Chain of Responsibility in Angular
Design Patterns — Memento in Angular
I’m not good at English. I write articles to practice English.