Welcome back to series about design pattern in JavaScript. If you like topic about design pattern in JavaScript, you can follow this link to see more. Design pattern in JavaScript series.
In this
article, we also learn about Proxy design pattern in JavaScript.
Table of contents:
- What is Proxy design pattern?
- How to implement Proxy design pattern?
- Practical application
Let’s go to
the content!
What is Proxy design pattern?
Proxy is a
structural design pattern that let you provide a substitude or placeholder for
another object. A proxy control access to the original object, allowing you to
perform something either before or after the request get through to the
original object.
What the
problems can the Proxy design pattern solve?
The access
to an object should be controlled.
Additional
functionally should be prouded when accessing an object.
When
accessing sensitive objects, for example, it shold be possible to check that
clients have the needed access rights.
How to
implement Proxy design pattern?
The service
interface (master object – MO) declares the interface (MO) of the Service. The
proxy must follow this interface to be able to disguise itself as a service
object.
Service is a
class that provides some useful business logic.
The proxy
class has a reference field that points to a service object. After the proxy
finishes its proccessing it passes the request to the service object.
The client
should work with both services and proxies, via the same interface. This way
you can pass a proxy into any code that expects a service object.
This is class diagram of Proxy design pattern.
Proxy design class diagram |
Practical
application
In this
article, we deal with a client-service problem. That is client will send
request and server will send response for client. Together we will build a
“stateless” API. Stateless means that when the client sends a request, the
server will response to that request and return the corresponding response. Even
if the request is repeated, the server will still send the same response. We
will do this through a fashion shop.
First we have
an API to get product information to return to the customer, when the customer
requests to see that product.
function GetProductAPI() {
this.getProduct = function (product) {
console.log('Product is got: ')
switch (product) {
case 'shirt':
return 'This is a white shirt!'
case 'watch':
return 'This is a nice watch!'
case 'glass':
return 'This is a royal glass.'
case 'hat':
return 'This is a best hat.'
default:
return 'You need choose one
product!'
}
}
}
Now we will
use this API when the customer needs to see the information of the products in
the shop.
const getProductAPI = new GetProductAPI()
console.log(getProductAPI.getProduct('shirt'))
// => Product is got
// => This is a white shirt!
console.log(getProductAPI.getProduct('watch'))
// => Product is got
// => This is a nice watch!
console.log(getProductAPI.getProduct('glass'))
// => Product is got
// => This is a royal glass.
console.log(getProductAPI.getProduct('hat'))
// => Product is got
// => This is a best hat.
console.log(getProductAPI.getProduct())
// => Product is got
// => You need choose one product!
You see
things going well. Customers send requests and receive product information they
want. And one day, your shop starts to be popular and has many users, what if
everyone wants to see the same product? Resources on your server are limited
and doing so will cost you a lot. At the same time, it will also increase the
risk of memory leaks of the server, worse, your server may terminate without
you wanting it.
To solve
this problem, we will create a "stateful" api. So stateful means that
we have a cache, the cache will remember previous requests. If new requests
have never been processed by the server, the server will process and store that
value in the cache. What requests have been processed by the server and have
been cached, when the clients send the request, the cache will send the correct
response to the user without having to send it back to the server.
This will
save server processing costs. Speed up results returned to users through
cache.
Now, let's
create a stateful api.
function GetProductProxy() {
this.api = new GetProductAPI()
this.cache = {}
this.getValue = function (product) {
if (!this.cache[product]) {
this.cache[product] = this.api.getProduct(product)
}
return this.cache[product]
}
}
We have a
proxy, which calls back to the original API and includes a cache to store
requests. If the request is new, it will be sent to the server for processing.
If it has been processed, it will be cached for future use.
const getProductProxy = new GetProductProxy()
console.log(getProductProxy.getValue('shirt'))
// => Product is got:
// => This is a white shirt!
console.log(getProductProxy.getValue('watch'))
// => Product is got:
// => This is a nice watch!
console.log(getProductProxy.getValue('glass'))
// => Product is got:
// => This is a royal glass.
console.log(getProductProxy.getValue('hat'))
// => Product is got:
// => This is a best hat.
console.log(getProductProxy.getValue(''))
// => Product is got:
// => You need choose one product!
console.log(getProductProxy.getValue('shirt'))
console.log(getProductProxy.getValue('shirt'))
console.log(getProductProxy.getValue('shirt'))
console.log(getProductProxy.getValue('hat'))
// => This is a white shirt!
// => This is a white shirt!
// => This is a white shirt!
// => This is a best hat.
You can see
that, when the request is processed by the server, there will be a
"Product is got" section. Once the requests have been processed and
cached, they will be returned to the clients without having to use the server.
We have just
built the Proxy design pattern and applied the theory of stateful and
stateless. Let's take a look at the pros and cons of the Proxy design pattern.
Pros:
You can
control the service object without clients knowing about it.
You can
manage the lifecycle of the service object when clients don’t care about it.
The proxy
works even if the service object isn’t ready or is not available.
Open/Closed
Principle. You can introduce new proxies without changing the service or
clients.
Cons:
The code may
become more complicated since you need to introduce a lot of new classes.
The response
from the service might get delayed.
Conclusion:
We just went
through the article about Proxy design pattern. Proxy pattern proved to be very
effective in handling pre-processed tasks. Reduce the burden on the server and
the cost that the server handles. Consider using the Proxy pattern in case your
connection handles the same task more than once.
If you have
any ideas, feel free to comment below. Thank you for joining with me. Have a
good day!
0 Nhận xét