본문 바로가기

2.분석 및 설계/Pattern

Chain of responsibility

들어가기

하나의 요청을 일련의 여러 객체에게 순서로 요청을 처리하며 요청을 각각의 객체로 전달이 되며, 중간에 요청 처리가 중단될 수도 있다. 일련의 여러 객체는 동적으로 구성이 가능하다.

작성자: http://ospace.tistory.com/,2010.10.22 (ospace114@empal.com)

코드

기본형태

기본 클래스로 연쇄 체인을 관리하는 객체

import java.util.*

abstract class Logger {
    public enum Cat { ERR, NOTICE, DEBUG }
    protected Cat mask protected Logger next; // 다음 연쇄되는 객체 저장용
    public void setNext ( Logger next ) {
        this.next = next;
    }

    public void message ( Cat pri, String msg ) {
        if ( pri <= this.mask ) {
            doMessage ( msg );

            if ( null != this.next ) {
                next.message ( pri, msg );
            }
        }
    }

    abstract protected void doMessage ( String msg );
}
class StdoutLogger extends Logger {
    public StdoutLogger () {
        this.mask = Logger.DEBUG;
    }

    protected void doMessage ( String msg ) {
        System.out.println ( "Writing to stdout: " + msg );
    }
}
class StderrLogger extends Logger {
    public StderrLogger () {
        this.mask = Logger.ERR;
    }

    protected void doMessage ( String msg ) {
        System.err.println ( "Sending to stderr: " + msg );
    }
}
Logger logger = new StdoutLogger ().setNext ( new StderrLogger () );
logger.message ( Logger.DEBUG, "call a function." );
logger.message ( Logger.ERR, "an error has occured." );

다음 객체 호출을 각 객체로 이관

아래는 다음 객체에 대한 호출 여부를 각각 객체에서 판단하도록 한다.

import java.util.*

abstract class Logger {
    public enum Cat { ERR, NOTICE, DEBUG }
    protected Logger next;// 다음 연쇄되는 객체 저장용
    public void setNext ( Logger next ) {
        this.next = next;
    }

    public void message ( Cat pri, String msg ) {
        doMessage ( pri, msg );
    }

    abstract protected void doMessage ( Cat pri, String msg );
}
class StdoutLogger extends Logger {
    public StdoutLogger () { }

    protected void doMessage ( Cat pri, String msg ) {
        if ( pri <= Logger.DEBUG ) {
            System.out.println ( "Writing to stdout: " + msg );
        }

        if ( this.next ) {
            next.doMessage ( pri, msg );
        }
    }
}
class StderrLogger extends Logger {
    public StderrLogger () {        this.mask = Logger.ERR;    }

    protected void doMessage ( Cat pri, String msg ) {
        if ( pri <= Logger.ERR ) {
            System.err.println ( "Sending to stderr: " + msg );
        }

        if ( this.next ) {
            next.doMessage ( pri, msg );
        }
    }
}

인터페이스 기반 구조

interface ILogger {
    enum Cat { ERR, NOTICE, DEBUG };
    bool doMessage ( Cat pri, String msg );

}

class LoggerChain {
    priate List list = new List();
    pubic void message ( Cat pri, String msg ) {
        for ( ILogger logger : list ) {
            if ( logger.doMessage ( pri, msg ) )
                break;
        }
    }

    public void addLogger ( ILogger logger ) {
        this.list.add ( logger );
    }
}
class StdoutLogger implement ILogger {

    public bool doMessage ( Cat pri, String msg ) {
        if ( ILogger.DEBUG < pri )
            return false;

        System.out.println ( "Writing to stdout: " + msg );

        return true;
    }
}
class StderrLogger implement ILogger {
    public bool doMessage ( Cat pri, String msg ) {
        if ( ILogger.ERR < pri )
            return false;

        System.out.println ( "Writing to stderr: " + msg );

        return true;
    }
}

참조

[1] http://ko.wikipedia.org/wiki/Chain_of_responsibility_%ED%8C%A8%ED%84%B4

반응형

'2.분석 및 설계 > Pattern' 카테고리의 다른 글

ThreadPool 개념과 구조  (0) 2012.07.27