1
+ const net = require ( 'net' ) ;
2
+ const http = require ( 'http' ) ;
3
+
4
+ // Abstract Product Class
5
+ class ApiRequest {
6
+ makeGetRequest ( url ) {
7
+ return Error ( "Implement make Get Request" ) ;
8
+ }
9
+ }
10
+
11
+ // Product A
12
+ class tcpApiRequest extends ApiRequest {
13
+ makeGetRequest ( url ) {
14
+ // Handling simple get request without query params
15
+ return new Promise ( ( resolve , reject ) => {
16
+ const socket = net . createConnection ( {
17
+ host : "www.example.com" ,
18
+ port : "80"
19
+ } ) ;
20
+
21
+ socket . on ( 'data' , ( data ) => resolve ( data . toString ( ) ) ) ;
22
+
23
+ socket . on ( 'error' , err => reject ( err ) )
24
+
25
+ socket . end ( `GET / HTTP/1.1\r\nHost: ${ url } \r\n\r\n` )
26
+ } )
27
+
28
+ }
29
+ }
30
+
31
+ // Product B
32
+ class httpApiRequest extends ApiRequest {
33
+ makeGetRequest ( url ) {
34
+ // Handling simple get request without query params
35
+ return new Promise ( ( resolve , reject ) => {
36
+ http . request ( `http://${ url } ` , ( res ) => {
37
+ res . on ( 'data' , data => resolve ( data . toString ( ) ) ) ;
38
+ res . on ( 'error' , err => reject ( err ) ) ;
39
+ } ) . end ( ) ;
40
+ } )
41
+
42
+ }
43
+ }
44
+
45
+ class ApiRequestFactory {
46
+ static createApiRequest ( kind ) {
47
+ // This can easily be extended to include HTTPS, HTTP2, HTTP3
48
+ switch ( kind ) {
49
+ case "tcp" :
50
+ return new tcpApiRequest ( ) ;
51
+ case "http" :
52
+ return new httpApiRequest ( ) ;
53
+ }
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Use this in another class making the product class
59
+ * and client class isolated
60
+ */
61
+ const apiRequest = ApiRequestFactory . createApiRequest ( "http" ) ;
62
+ apiRequest . makeGetRequest ( "example.com" )
63
+ . then ( respone => console . log ( respone ) )
64
+ . catch ( err => console . log ( err ) ) ;
0 commit comments