倭マン's BLOG

くだらない日々の日記書いてます。 たまにプログラミング関連の記事書いてます。 書いてます。

「GoF デザインパターン」アノテーション (12) : Proxy パターン

今回は Proxy パターン一覧)。

Proxy パターンの登場人物

  • @Subject → 型
  • @RealSubject → 型
    • subjectType : Class<?>
  • @Proxy → 型
    • subjectType : Class<?>
    • @RealSubjectInstance → フィールド
  • @Client → 型
    • subjectType : Class<?>

アノテーション定義


上記の定義の具体的な Java コード。

package org.waman.tools.design.gof.structural;

import java.lang.annotation.*;

public final class ProxyPattern {
    
    private ProxyPattern(){}

    @Target(ElementType.TYPE)
    public static @interface Subject{}

    @Target(ElementType.TYPE)
    public static @interface RealSubject{
        Class<?> subjectType() default Void.class;
    }

    @Target(ElementType.TYPE)
    public static @interface Proxy{

        Class<?> subjectType() default Void.class;

        @Inherited @Target(ElementType.FIELD)
        public static @interface RealSubjectInstance{}
    }

    /** GoF 本には定義されていません。 */
    @Target(ElementType.TYPE)
    public static @interface Client{
        Class<?> subjectType() default Void.class;
    }
}

サンプルコード in 『Java 言語で学ぶデザインパターン入門』


Printable.java

@Subject 役のインターフェース。

import org.waman.tools.design.gof.structural.ProxyPattern;

@ProxyPattern.Subject
public interface Printable {
    void setPrinterName(String name);
    String getPrinterName();
    void print(String string);
}

Printer.java

@RealSubject 役のクラス。

import org.waman.tools.design.gof.structural.ProxyPattern;

@ProxyPattern.RealSubject(subjectType = Printable.class)
public class Printer implements Printable {
    ...
    @Override public void setPrinterName(String name) {...}
    @Override public String getPrinterName() {...}
    @Override public void print(String string) {...}
}

PrinterProxy.java

@Proxy 役のクラス。

import org.waman.tools.design.gof.structural.ProxyPattern;
import org.waman.tools.design.gof.structural.ProxyPattern.Proxy.RealSubjectInstance;

@ProxyPattern.Proxy(subjectType = Printable.class)
public class PrinterProxy implements Printable {

    @RealSubjectInstance private Printer real;
    ...
    
    @Override public synchronized void setPrinterName(String name) {...}
    @Override public String getPrinterName() {...}
    @Override public void print(String string) {...}
}

Main.java

@Client 役のクラス。

import org.waman.tools.design.gof.structural.ProxyPattern;

@ProxyPattern.Client(subjectType = Printable.class)
public class Main {
    
    public static void main(String[] args) {
        Printable p = new PrinterProxy("Alice");
        System.out.println("名前は現在" + p.getPrinterName() + "です。");
        
        p.setPrinterName("Bob");
        System.out.println("名前は現在" + p.getPrinterName() + "です。");
        
        p.print("Hello, world.");
    }
}

増補改訂版Java言語で学ぶデザインパターン入門 オブジェクト指向における再利用のためのデザインパターン