THN Interview Prep

Proxy (Structural)

Intent / problem it solves

Provide a surrogate controlling access: lazy loading, access control, logging, remote stub, caching.

When to use / when NOT

Use when creation is expensive, cross-process calls need marshalling, or you must guard sensitive operations.

Avoid when indirection adds latency without benefit or when Decorator semantics (stacking behavior) fit better.

Structure

Proxy implements the same interface as the real subject; forwards calls, optionally caching or deferring.

Loading diagram…

Go example

package main

import (
	"fmt"
	"sync"
	"time"
)

type ReportGenerator interface {
	Summary() string
}

type HeavyReport struct {
	cache string
}

func (report *HeavyReport) materialize() {
	time.Sleep(10 * time.Millisecond)
	report.cache = "quarterly snapshot"
}

func (report *HeavyReport) Summary() string {
	if report.cache == "" {
		report.materialize()
	}
	return report.cache
}

type LazyReportProxy struct {
	once   sync.Once
	target *HeavyReport
}

func (proxy *LazyReportProxy) Summary() string {
	var result string
	proxy.once.Do(func() {
		proxy.target = &HeavyReport{}
	})
	result = proxy.target.Summary()
	return result
}

func main() {
	proxy := &LazyReportProxy{}
	fmt.Println(proxy.Summary())
}

JavaScript example

class GeoService {
  constructor() {
    this.loaded = false;
  }

  fetchBoundary(regionCode) {
    if (!this.loaded) {
      this.loaded = true;
    }
    return { regionCode, boundary: 'polygon' };
  }
}

class GeoServiceProxy {
  constructor(inner) {
    this.inner = inner;
    this.cache = new Map();
  }

  fetchBoundary(regionCode) {
    if (this.cache.has(regionCode)) {
      return this.cache.get(regionCode);
    }
    const fresh = this.inner.fetchBoundary(regionCode);
    this.cache.set(regionCode, fresh);
    return fresh;
  }
}

const remote = new GeoServiceProxy(new GeoService());
console.log(remote.fetchBoundary('us-ca'));
console.log(remote.fetchBoundary('us-ca'));

Interview phrase

“Proxy stands in front of the real object to lazy-init, cache, or enforce auth—same interface, different control point.”

Connect to LLD for lazy repositories, permission gates, or remote clients in LLD case studies.

Last updated on

Spotted something unclear or wrong on this page?

On this page