반응형
책임연쇄패턴
1. java 1
next chain을 받는 함수를 만드는 것이 아니라 LinkedList를 이용했습니다.
package chainofresposibility;
import java.util.LinkedList;
import java.util.List;
public class Main {
public static void main(String[] args) {
LoggerManager manager = new LoggerManager();
manager.setLogger(new ConsoleLogger(LoggerManager.ERROR));
manager.setLogger(new FileLogger(LoggerManager.WRAN));
manager.write(LoggerManager.ERROR,"eeeeeeeeeee");
manager.write(LoggerManager.WRAN,"wwwwwwwwwww");
manager.write(LoggerManager.DEBUG,"ddddddddddd");
}
}
interface ILogger{
void write(int level, String msg);
}
class LoggerManager implements ILogger{
public static int ERROR = 3;
public static int WRAN = 2;
public static int DEBUG = 1;
private List<ILogger> loggers = new LinkedList<>();
public void setLogger(ILogger logger){
loggers.add(logger);
}
@Override
public void write(int level, String msg) {
for(ILogger l : loggers){
l.write(level, msg);
}
}
}
class ConsoleLogger implements ILogger{
private int levels;
ConsoleLogger(int levels){
this.levels = levels;
}
@Override
public void write(int levels, String msg) {
if(this.levels<=levels){
System.out.println("ConsoleLogger : "+msg);
}
}
}
class FileLogger implements ILogger{
private int levels;
FileLogger(int levels){
this.levels = levels;
}
@Override
public void write(int levels, String msg) {
if(this.levels<=levels){
System.out.println("FileLogger : "+msg);
}
}
}
결과
ConsoleLogger : eeeeeeeeeee
FileLogger : eeeeeeeeeee
FileLogger : wwwwwwwwwww
Process finished with exit code 0
2. java
이것은 next chain을 호출합다. 1, 2번 다 연속으로 호출됩니다.
package chanofresposibility;
public class Main {
public static void main(String[] args) {
System.out.println("main");
Logger consoleLogger = new ConsoleBasedLogger(Logger.OUTPUT);
Logger debugLogger = new DebugBasedLogger(Logger.DEBUG);
consoleLogger.setNextLogger(debugLogger);
Logger errorLogger = new ErrorBasedLogger(Logger.ERROR);
debugLogger.setNextLogger(errorLogger);
consoleLogger.logMessage(Logger.OUTPUT, "111111111111 ");
consoleLogger.logMessage(Logger.ERROR, "222222222222");
consoleLogger.logMessage(Logger.DEBUG, "3333333333333");
}
}
abstract class Logger{
public static int OUTPUT = 1;
public static int ERROR = 2;
public static int DEBUG = 3;
protected int levels;
protected Logger nextLogger;
public void setNextLogger(Logger nextLogger){
this.nextLogger = nextLogger;
}
public void logMessage(int levels, String msg){
if(this.levels <= levels){
displayLogInfo(msg);
}
if(nextLogger != null){
nextLogger.logMessage(levels, msg);
}
}
protected abstract void displayLogInfo(String msg);
}
class ConsoleBasedLogger extends Logger{
public ConsoleBasedLogger(int levels){
this.levels = levels;
}
@Override
protected void displayLogInfo(String msg) {
System.out.println(("ConsoleBasedLogger : "+msg));
}
}
class DebugBasedLogger extends Logger{
public DebugBasedLogger (int levels){
this.levels = levels;
}
@Override
protected void displayLogInfo(String msg) {
System.out.println((" DebugBasedLogger : "+msg));
}
}
class ErrorBasedLogger extends Logger {
public ErrorBasedLogger(int levels) {
this.levels=levels;
}
@Override
protected void displayLogInfo(String msg) {
System.out.println(" ErrorBasedLogger : "+msg);
}
}
3. kotlin
이건 좀 다른 예제 입니다. 코틀린 이여서 한 번 따라 해 봤습니다.
package chainofresponsibility
fun main() {
println("chain of ")
// 연쇄적인 엘리먼트 만들기
val authenticationHeader = AuthHeader("123456")
val contentTypeHeader = ContentTypeHeader("json")
val messageBody = BodyPayload("Body:\n{\n\"username\"=\"dbacinski\"\n}")
// 체인 구조
authenticationHeader.next = contentTypeHeader
contentTypeHeader.next = messageBody
// 체인 실행
val messageWithAuthentication = authenticationHeader.addHeader("Headers with Authentication:\n")
println(messageWithAuthentication)
val messageWithoutAuth = contentTypeHeader.addHeader("Headers:\n")
println(messageWithoutAuth)
}
interface HeaderChain{
fun addHeader(inputHeader:String):String
}
class AuthHeader(val token:String?, var next:HeaderChain?=null):HeaderChain{
override fun addHeader(inputHeader: String): String {
token?: throw IllegalStateException("Token should be not null")
println(">>>> AuthHeader ${inputHeader}")
return inputHeader + "Auth : ${token}\n".let {
println(">>>> ContentTypeHeader it ${it}")
next?.addHeader(it)?:it
}
}
}
class ContentTypeHeader(val contentType:String, var next:HeaderChain?=null) : HeaderChain{
override fun addHeader(inputHeader: String): String {
println(">>>> ContentTypeHeader ${inputHeader}")
return inputHeader + "ContentType:${contentType}\n".let {
println(">>>> ContentTypeHeader it ${it}")
next?.addHeader(it) ?: it
}
}
}
class BodyPayload(val body:String, var next:HeaderChain? = null) : HeaderChain{
override fun addHeader(inputHeader: String): String {
println(">>>> BodyPayload ${inputHeader}")
return inputHeader +" $body".let {
println(">>>> BodyPayload it ${it}")
next?.addHeader(it)?:it
}
}
}
//https://medium.com/hongbeomi-dev/design-pattern-in-kotlin-1-behavioral-7185d0f71aea
//https://develogs.tistory.com/18