1. Definition
The Proxy Design Pattern provides a surrogate or placeholder for another object to control access to it. The primary reason for using a proxy is to act as a controlling intermediary between a client and the real object.
2. Problem Statement
There are situations when we want to add some functionality to an object, but we don't want to modify its structure. This could be for access control, lazy initialization, logging, etc.
3. Solution
The Proxy pattern suggests creating a new proxy class with the same interface as the original object. This proxy class can then wrap the original object, adding additional behaviors and controlling access to it.
4. Real-World Use Cases
1. Lazy loading of a heavyweight object.
2. Access control to resources or operations.
3. Logging access and operations for debugging or auditing purposes.
5. Implementation Steps
1. Define the common interface for both the RealObject and the Proxy.
2. Create the Proxy class that holds a reference to the RealObject.
3. Implement the proxy methods, adding the desired functionality before or after calling the real object's methods.
6. Implementation in Ruby
# Step 1: Common Interface
class AbstractObject
def request
raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
end
end
# Step 2: RealObject
class RealObject < AbstractObject
def request
"RealObject: Handling request."
end
end
# Step 3: Proxy Object
class ProxyObject < AbstractObject
def initialize(real_object)
@real_object = real_object
end
def request
# Additional behavior (e.g., logging, access control)
if access_granted?
@real_object.request + " (handled by Proxy)"
else
"Proxy: Access denied."
end
end
private
def access_granted?
# Simulate access control check
true
end
end
# Client code
proxy = ProxyObject.new(RealObject.new)
puts proxy.request
Output:
RealObject: Handling request. (handled by Proxy)
Explanation:
1. The AbstractObject class provides a common interface for both RealObject and ProxyObject.
2. RealObject is the actual object that performs the primary function.
3. ProxyObject wraps around RealObject and can control access to it, or add additional functionalities. In this example, it checks access using the access_granted? method and then lets the RealObject handle the request.
4. The client interacts with the ProxyObject, which in turn interacts with the RealObject when appropriate.
7. When to use?
Use the Proxy pattern when:
1. You need a more versatile or sophisticated reference to an object than just a pointer.
2. You want to lazy-initialize your heavy objects only when they're needed.
3. You need to log, monitor, or secure access to the actual object without changing it.
Comments
Post a Comment