Proxy Pattern

Proxy pattern refers to structural design patterns.
The pattern describes the technique of working with the class through the class layer – 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 class interface.
Imagine the situation – in 2015, one of the countries of Western Europe decides to record all requests to the websites of users of the country, in order to improve statistics and an in-depth understanding of the political view of citizens.
Imagine a pseudo-code of naive gateway implementation used by citizens 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 above code, we create an Internet router class, with a pointer to an object that provides Internet access. When a client requests a site, we will return a response from the Internet.

Using the Proxy pattern and the singleton antipattern, add the logging functionality of 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 saving the original InternetRouter interface in the InternetRouterProxy proxy class, it is enough to replace the initialization class from InternerRouter to its proxy, no more changes to the code base are required.

References

https://refactoring.guru/design-patterns/proxy