โ† Kembali ke Design Pattern
๐Ÿชž
Structural

Proxy

Menyediakan pengganti (placeholder) yang mengontrol akses ke objek lain, untuk menambahkan lazy loading, caching, atau pengecekan akses.

Masalahnya

Objek yang berat (panggilan jaringan, database, file besar) tidak seharusnya dibuat atau diakses sebelum benar-benar dibutuhkan. Kamu ingin menambahkan kontrol akses atau caching tanpa menyentuh class aslinya.

Cara Kerja

  • โ€บClient berinteraksi dengan proxy melalui interface yang sama dengan objek aslinya
  • โ€บVirtual proxy: menunda pembuatan objek yang mahal sampai pertama kali dipakai (lazy initialization)
  • โ€บCaching proxy: mengingat hasil dan mengembalikan salinan dari cache
  • โ€บProtection proxy: memeriksa izin sebelum mendelegasikan
  • โ€บRemote proxy: merepresentasikan objek yang berada di address space lain

Kapan Digunakan

โœ“Lazy initialization untuk objek yang boros resource
โœ“Caching untuk menghindari operasi mahal yang berulang
โœ“Kontrol akses: verifikasi izin sebelum sebuah operasi diizinkan
โœ“Logging atau monitoring akses ke objek yang sensitif

Contoh di Dunia Nyata

๐ŸŽ
iOS

lazy var properties, SDWebImage lazy image loading, CoreData faulting

๐Ÿค–
Android

by lazy delegate, Glide placeholder images, ViewModel lazy init

๐ŸŒ
Web

ES6 Proxy, service workers as network proxies, memoization helpers

Contoh Kode

Swift
protocol ImageLoader {
    func load(url: String) -> String
}

class RealImageLoader: ImageLoader {
    func load(url: String) -> String {
        print("Network: loading \(url)")
        return "ImageData(\(url))"
    }
}

// Caching proxy
class ImageLoaderProxy: ImageLoader {
    private let real  = RealImageLoader()
    private var cache = [String: String]()

    func load(url: String) -> String {
        if let cached = cache[url] { print("Cache hit"); return cached }
        let data = real.load(url: url)
        cache[url] = data
        return data
    }
}

let loader: ImageLoader = ImageLoaderProxy()
loader.load(url: "https://example.com/photo.jpg")  // Network load
loader.load(url: "https://example.com/photo.jpg")  // Cache hit