Proxy Design Pattern in Swift

1. Definition

The Proxy Design Pattern provides a surrogate or placeholder for another object to control access to it. The main object is often called the "Real Subject", and the proxy either interfaces its access or provides additional functionalities like lazy initialization, logging, or access control.

2. Problem Statement

Imagine you have a large object, such as a detailed image or a remote database object. Direct operations on the main object can be expensive in terms of computational resources, or you may want to control the access to this object for security reasons.

3. Solution

Using the Proxy pattern, you create an intermediary that can perform additional tasks like lazy loading, logging, and controlling access to the main object, without clients being aware of the proxy's presence.

4. Real-World Use Cases

1. Virtual proxy: Loading an image only when it's required to be displayed.

2. Protection proxy: Controlling access to sensitive methods or databases.

3. Remote proxy: Representing objects that are in different address spaces or servers.

5. Implementation Steps

1. Define an interface that both the RealSubject and Proxy classes will implement.

2. Create the RealSubject class that provides the real operations.

3. Create the Proxy class that maintains a reference to the RealSubject and controls its access or augments its functionalities.

6. Implementation in Swift Programming

// 1. Interface for both RealSubject and Proxy
protocol Subject {
    func request() -> String
}
// 2. RealSubject class
class RealSubject: Subject {
    func request() -> String {
        return "RealSubject: Handling request."
    }
}
// 3. Proxy class
class Proxy: Subject {
    private lazy var realSubject: RealSubject = RealSubject()
    func request() -> String {
        // Proxy can add pre-processing or lazy initialization
        return "Proxy: Doing some checks...\n" + realSubject.request() + "\nProxy: All done."
    }
}
// Client Code
let proxy = Proxy()
print(proxy.request())

Output:

Proxy: Doing some checks...
RealSubject: Handling request.
Proxy: All done.

Explanation:

1. Both RealSubject and Proxy adhere to the Subject interface.

2. The Proxy class has a reference to RealSubject but initializes it lazily, only when required.

3. When the client makes a request via the proxy, the proxy can perform additional tasks before/after the real subject performs the actual operation.

7. When to use?

Use the Proxy pattern when:

1. You need to represent a heavy object that consumes vast resources, and you want to delay its loading or initialization.

2. You need to control access to the object based on certain criteria.

3. You want to introduce a layer between your application's core components and external resources, like network communication or file systems.


Comments