/
factory-method.js
134 lines (124 loc) · 3.75 KB
/
factory-method.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// Abstract class called PaymentMethod
class PaymentMethod {
constructor() {
if (this.constructor === PaymentMethod) {
throw new Error("Cannot instantiate abstract class!");
}
}
connectToGateway() {
throw new Error("This method must be overwritten!");
}
pay(amount) {
throw new Error("This method must be overwritten!");
}
}
// Concrete class called CreditCard
class CreditCard extends PaymentMethod {
#gateway;
constructor(cardNumber, cardHolder, expiryDate) {
super();
this.#gateway = this.connectToGateway(cardNumber, cardHolder, expiryDate);
}
connectToGateway(cardNumber, cardHolder, expiryDate) {
console.log('Connecting to payment gateway...');
}
pay(amount) {
console.log(`Paying $${amount} using Credit Card`);
}
}
// Concrete class called PayPal
class PayPal extends PaymentMethod {
#gateway;
constructor(email, password) {
super();
this.#gateway = this.connectToGateway(email, password);
}
connectToGateway(email, password) {
console.log('Connecting to payment gateway...');
}
pay(amount) {
console.log(`Paying $${amount} using PayPal`);
}
}
// Concrete class called BitPay
class BitPay extends PaymentMethod {
#gateway;
constructor(email, password) {
super();
this.#gateway = this.connectToGateway(email, password);
}
connectToGateway(email, password) {
console.log('Connecting to payment gateway...');
}
pay(amount) {
console.log(`Paying $${amount} using BitPay`);
}
}
// Abstract factory method to create payment methods
class PaymentMethodFactory {
constructor() {
if (this.constructor === PaymentMethodFactory) {
throw new Error("Cannot instantiate abstract class!");
}
}
createPaymentMethod() {
throw new Error("This method must be overwritten!");
}
}
// Concrete factory method to create CreditCard payment methods
class CreditCardPaymentMethodFactory extends PaymentMethodFactory {
#cardNumber;
#cardHolder;
#expiryDate;
constructor(cardNumber, cardHolder, expiryDate) {
super();
this.#cardNumber = cardNumber;
this.#cardHolder = cardHolder;
this.#expiryDate = expiryDate;
}
createPaymentMethod() {
return new CreditCard(this.#cardNumber, this.#cardHolder, this.#expiryDate);
}
}
// Concrete factory method to create PayPal payment methods
class PayPalPaymentMethodFactory extends PaymentMethodFactory {
#email;
#password;
constructor(email, password) {
super();
this.#email = email;
this.#password = password;
}
createPaymentMethod() {
return new PayPal(this.#email, this.#password);
}
}
// Concrete factory method to create BitPay payment methods
class BitPayPaymentMethodFactory extends PaymentMethodFactory {
#email;
#password;
constructor(email, password) {
super();
this.#email = email;
this.#password = password;
}
createPaymentMethod() {
return new BitPay(this.#email, this.#password);
}
}
// Class that will use the factory method to create payment methods
class PaymentProcessor {
#paymentMethodFactory;
#paymentMethod;
constructor(paymentMethodFactory) {
this.#paymentMethodFactory = paymentMethodFactory;
}
processPayment(amount) {
this.#paymentMethod = this.#paymentMethodFactory.createPaymentMethod();
this.#paymentMethod.pay(amount);
}
}
// Usage
const creditCardPaymentMethodFactory = new CreditCardPaymentMethodFactory('123123', 'John Doe', '12/23');
const paymentProcessor = new PaymentProcessor(creditCardPaymentMethodFactory);
paymentProcessor.processPayment(100);