1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【デザインパターン】プロキシパターン解説(Flutter/Android 実例付き)

1
Last updated at Posted at 2025-09-01

1. パターンの意図

プロキシ(Proxy)パターンは、
本物のオブジェクト(RealSubject)へのアクセスを代理するオブジェクトを提供するデザインパターンです。

解決する問題

  • オブジェクトの生成やアクセスにコストが高い(遅延生成したい)
  • セキュリティーのためアクセス制御したい
  • ネットワーク越しのリモート呼び出しを隠蔽したい

ポイント

  • Subject:共通インターフェース
  • RealSubject:本物の処理を行うクラス
  • Proxy:RealSubject と同じインターフェースを持ち、呼び出しを委譲(+制御やキャッシュを追加)

2. UML 図


3. Flutter / Dart 実装例

Subject

abstract class Image {
  void display();
}

RealSubject

class RealImage implements Image {
  final String filename;

  RealImage(this.filename) {
    _loadFromDisk(filename);
  }

  void _loadFromDisk(String filename) {
    print("Loading $filename from disk...");
  }

  @override
  void display() {
    print("Displaying $filename");
  }
}

Proxy

class ProxyImage implements Image {
  RealImage? _realImage;
  final String filename;

  ProxyImage(this.filename);

  @override
  void display() {
    _realImage ??= RealImage(filename); // 遅延ロード
    _realImage!.display();
  }
}

利用例

void main() {
  Image image = ProxyImage("anna.png");

  // 初回はロードが走る
  image.display();
  // 2回目以降はキャッシュ利用
  image.display();
}

出力:

Loading anna.png from disk...
Displaying anna.png
Displaying anna.png

4. Android / Kotlin 実装例

Subject

interface Image {
    fun display()
}

RealSubject

class RealImage(private val filename: String) : Image {
    init {
        loadFromDisk(filename)
    }

    private fun loadFromDisk(filename: String) {
        println("Loading $filename from disk...")
    }

    override fun display() {
        println("Displaying $filename")
    }
}

Proxy

class ProxyImage(private val filename: String) : Image {
    private var realImage: RealImage? = null

    override fun display() {
        if (realImage == null) {
            realImage = RealImage(filename)
        }
        realImage?.display()
    }
}

利用例

fun main() {
    val image: Image = ProxyImage("anna.png")

    image.display() // 初回はロードあり
    image.display() // 2回目はキャッシュ利用
}

5. プロキシの種類

  • Virtual Proxy:コストの高いオブジェクトを遅延生成(例:画像やDB接続)
  • Protection Proxy:アクセス制御(例:ユーザー権限に応じて呼び出し可否を制御)
  • Remote Proxy:リモートオブジェクトをローカルから操作(例:gRPC, REST API 呼び出し)
  • Cache Proxy:結果をキャッシュして効率化(例:Webキャッシュ、DBクエリキャッシュ)

6. 実務ユースケース

Flutter

  • 遅延ロードの画像/リソースラッパ
  • 認証状態に応じたサービス呼び出し制御
  • Provider や Repository に Proxy を噛ませてキャッシュ管理

Android / Kotlin

  • Retrofit + OkHttp の Interceptor による Proxy 的挙動
  • Room DB アクセスの Proxy ラッパ
  • 権限管理付き Repository(Protection Proxy)

7. Decorator との違い

項目 Proxy Decorator
共通点 同じインターフェースを持ち、呼び出しを委譲 同じインターフェースを持ち、呼び出しを委譲
目的 アクセス制御・遅延生成 機能追加・拡張
Virtual Proxy = 遅延ロード、Protection Proxy = 認可 コーヒーにミルク/砂糖追加、Padding(Text)

まとめ

  • Proxy パターンは「代理人」
  • 本物のオブジェクトへのアクセスをコントロールする
  • Flutter/Android ではキャッシュ・遅延ロード・アクセス制御の場面でよく使われる
  • Decorator が“拡張”、Proxy が“制御” というのが最大の違い

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?