倭マン's BLOG

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

「GoF デザインパターン」アノテーション (13) : Chain of Responsibility パターン

今回は Chain of Responsibility パターン一覧)。

Chain of Responsibility パターンの登場人物

  • @Handler → 型
    • @Next → フィールド
    • @Request → メソッド
  • @ConcreteHandler → 型
    • handlerType : Class<?>
  • Client → 型
    • handlerType : Class<?>

アノテーション定義


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

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

import java.lang.annotation.*;

public final class ChainOfResponsibilityPattern {
    
    private ChainOfResponsibilityPattern(){}

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

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

        @Inherited @Target(ElementType.METHOD)
        public static @interface Request{}
    }

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

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

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


Support.java

@Handler 役のクラス。

import org.waman.tools.design.gof.behavioral.ChainOfResponsibilityPattern;
import org.waman.tools.design.gof.behavioral.ChainOfResponsibilityPattern.Handler.Next;
import org.waman.tools.design.gof.behavioral.ChainOfResponsibilityPattern.Handler.Request;

@ChainOfResponsibilityPattern.Handler
public abstract class Support {
    ...
    @Next private Support next;
    ...
    @Request public void support(Trouble trouble) {
        if (resolve(trouble))
            done(trouble);
        
        else if (next != null)
            next.support(trouble);
        
        else
            fail(trouble);
    }
    
    protected abstract boolean resolve(Trouble trouble);
    
    protected void done(Trouble trouble) {
        System.out.println(trouble + " is resolved by " + this + ".");
    }
    
    protected void fail(Trouble trouble) {
        System.out.println(trouble + " cannot be resolved.");
    }
}

SpecialSupport.java, OddSupport.java

@ConcreteHandler 役の具象クラス。

import org.waman.tools.design.gof.behavioral.ChainOfResponsibilityPattern;

@ChainOfResponsibilityPattern.ConcreteHandler(handlerType = Support.class)
public class SpecialSupport extends Support {
    
    private int number;
    
    public SpecialSupport(String name, int number) {
        super(name);
        this.number = number;
    }
    
    @Override
    protected boolean resolve(Trouble trouble) {
        if (trouble.getNumber() == number)
            return true;
        else
            return false;
    }
}
import org.waman.tools.design.gof.behavioral.ChainOfResponsibilityPattern;

@ChainOfResponsibilityPattern.ConcreteHandler(handlerType = Support.class)
public class OddSupport extends Support {
    
    public OddSupport(String name) {
        super(name);
    }
    
    @Override
    protected boolean resolve(Trouble trouble) {
        if (trouble.getNumber() % 2 == 1)
            return true;
        else
            return false;
    }
}

Main.java

@Client 役のクラス。

import org.waman.tools.design.gof.behavioral.ChainOfResponsibilityPattern;

@ChainOfResponsibilityPattern.Client(handlerType = Support.class)
public class Main {
    
    public static void main(String[] args) {
        
        Support charlie = new SpecialSupport("Charlie", 429);
        Support elmo    = new OddSupport("Elmo");
        
        charlie.setNext(elmo);
        
        for (int i = 0; i < 500; i += 33)
            charlie.support(new Trouble(i));
    }
}

増補改訂版Java言語で学ぶデザインパターン入門 オブジェクト指向における再利用のためのデザインパターン Code Complete第2版〈上〉―完全なプログラミングを目指して Code Complete第2版〈下〉―完全なプログラミングを目指して