| name | apply-proxy-pattern |
| description | Use when you need to control access to an object — adding lazy initialization, access control, logging, caching, or remote access — without changing the object's interface or the client's code. |
| source | Gamma, Helm, Johnson, Vlissides, "Design Patterns: Elements of Reusable Object-Oriented Software" (1994) pp. 207–217; Java RMI (remote proxy); Spring AOP (@Transactional, @Cacheable use proxies); Python unittest.mock; Hibernate lazy loading |
| tags | ["design-patterns","structural","proxy","oop","developer","access-control","lazy-loading","caching"] |
| related | ["apply-decorator-pattern","apply-facade-pattern","apply-solid-principles"] |
Apply Proxy Pattern
Provide a surrogate or placeholder for another object to control access to it.
Why This Is Best Practice
Adopted by: Spring Framework's AOP (every @Transactional and @Cacheable bean
is a proxy — used in the majority of Spring applications), Java RMI (remote proxy for
distributed objects — Java's original distributed computing model), Hibernate's lazy
loading (collection proxies — default in every Hibernate application), and Python's
unittest.mock (a virtual proxy over any object).
Impact: Spring's transaction proxy is cited in the Spring documentation as the
reason requires no manual connection management — 80%+ reduction in
transaction-handling boilerplate (Spring documentation). Hibernate's virtual proxy for
lazy loading avoids loading entire object graphs; without it, a single entity load
triggers cascading database queries.
Adding cross-cutting concerns (logging, auth, caching) directly to the
subject class violates SRP — the class now handles both its own logic and the concern.
A proxy keeps the subject focused while the proxy layer intercepts access.