The Proxy pattern is a structural design pattern.
The pattern describes the technique of working with a class through a class interlayer – a proxy. The proxy allows you to change the functionality of the original class, with the ability to preserve the original behavior, while maintaining the original interface of the class.
Let’s imagine a situation – in 2015, one of the countries of Western Europe decides to record all requests to the websites of the country’s users, in order to improve statistics and gain a deeper understanding of the political moods of citizens.
Let’s present a pseudo-code of a naive implementation of a gateway that citizens use to access the Internet:
class InternetRouter {
private let internet: Internet
init(internet: Internet) {
self.internet = internet
}
func handle(request: Request, from client: Client) -> Data {
return self.internet.handle(request)
}
}
In the code above, we create an Internet router class, with a pointer to an object providing access to the Internet. When a client requests a site, we return a response from the Internet.
Using the Proxy pattern and the singleton anti-pattern, we will add the functionality of logging the client name and URL:
class InternetRouterProxy {
private let internetRouter: InternetRouter
init(internet: Internet) {
self.internetRouter = InternetRouter(internet: internet)
}
func handle(request: Request, from client: Client) -> Data {
Logger.shared.log(“Client name: \(client.name), requested URL: \(request.URL)”)
return self.internetRouter.handle(request: request, from: client)
}
}
Due to the preservation of the original InternetRouter interface in the InternetRouterProxy proxy class, it is enough to replace the initialization class from InternetRouter to its proxy, no further changes to the code base are required.
Sources
https://refactoring.guru/ru/design-patterns/ proxy