일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- Spring Batch
- 요리
- devops
- elasticsearch
- IntelliJ
- jsp
- javascript
- MySQL
- db
- jenkins
- java
- Git
- 맛집
- springboot
- Spring Boot
- ReactJS
- php
- Oracle
- Design Patterns
- AWS
- laravel
- JVM
- it
- linux
- redis
- tool
- Web Server
- Spring
- ubuntu
- Gradle
Archives
- Today
- Total
아무거나
[Design Pattern] Chain of Responsibility Pattern 본문
반응형
책임 사슬 패턴(Chain of Responsibility Pattern)
다양한 처리
방식을 유연
하게 연결할 수 있다.
Handler가 다음번에 처리할 객체들을 가지고 있어가지고 자기가 가지고 있는 프로세스가 실패할 경우 다음번 객체(=ConcreteHandler ..)로 넘겨주는 설계방식
책임 사슬 패턴 예시 - 1
사칙 연산을 하는 프로그램
Calculator 클래스 선언
[Calculator.java]
package com.bkjeon.chain_of_responsibility;
public abstract class Calculator {
private Calculator nextCalculator;
public void setNextCalculator(Calculator nextCalculator) {
this.nextCalculator = nextCalculator;
}
public boolean process(Request request) {
if (operator(request)) {
return true;
} else {
if (nextCalculator != null) {
return nextCalculator.process(request);
}
}
return false;
}
abstract protected boolean operator(Request request);
}
[Request.java]
package com.bkjeon.chain_of_responsibility;
public class Request {
int a,b;
String operator;
public Request(int a, int b, String operator) {
super();
this.a = a;
this.b = b;
this.operator = operator;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
public String getOperator() {
return operator;
}
public void setOperator(String operator) {
this.operator = operator;
}
}
[PlusCalculator.java]
package com.bkjeon.chain_of_responsibility;
public class PlusCalculator extends Calculator {
@Override
protected boolean operator(Request request) {
if (request.getOperator().equals("+")) {
int a = request.getA();
int b = request.getB();
int result = a + b;
System.out.println(a + "+" + b + "=" + result);
}
return false;
}
}
[SubCalculator.java]
package com.bkjeon.chain_of_responsibility;
public class SubCalculator extends Calculator {
@Override
protected boolean operator(Request request) {
if (request.getOperator().equals("-")) {
int a = request.getA();
int b = request.getB();
int result = a - b;
System.out.println(a + "-" + b + "=" + result);
}
return false;
}
}
[Main.java]
package com.bkjeon.chain_of_responsibility;
public class Main {
public static void main(String[] args) {
Calculator plus = new PlusCalculator();
Calculator sub = new SubCalculator();
plus.setNextCalculator(sub);
Request request1 = new Request(1, 2, "+");
Request request2 = new Request(10, 2, "-");
plus.process(request1);
plus.process(request2);
}
}
[실행결과]
1+2=3
10-2=8
PlusCalculator 에서 처리를 하되 처리를 못할 경우에는 setNextCalculator에 넘겨준 다음 동작인 SubCalculator 처리를 한다.
만약 나중 실행인 SubCalculator 연산이 먼저 되게 하려면 아래와 같이 Calculator를 수정하자.
[Calculator.java]
package com.bkjeon.chain_of_responsibility;
public abstract class Calculator {
// private Calculator nextCalculator;
private Calculator preCalculator;
public void setNextCalculator(Calculator nextCalculator) {
// this.nextCalculator = nextCalculator;
this.preCalculator = nextCalculator;
}
public boolean process(Request request) {
// 처음 프로세스 실행 후 문제가 생기면 다음 프로세스 실행
// if (operator(request)) {
// return true;
// } else {
// if (nextCalculator != null) {
// return nextCalculator.process(request);
// }
// }
// return false;
// 먼저 다른 프로세스에 넘긴 다음에 다른 프로세스가 처리를 못하면 처음의 프로세스가 처리를 한다.
if (preCalculator != null) {
if (preCalculator.process(request)) {
return true;
}
}
return operator(request);
}
abstract protected boolean operator(Request request);
}
책임 사슬 패턴 예시 - 2
게임에서 공격을 받고 처리하는 부분을 구현해보자.
공격 클래스를 구현
[Attack.java]
package com.bkjeon.chain_of_responsibility.example2;
public class Attack {
private int amount;
public Attack(int amount) {
this.amount = amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public int getAmount() {
return amount;
}
}
방어 기능에 대한 인터페이스를 구현
[Defense.java]
package com.bkjeon.chain_of_responsibility.example2;
public interface Defense {
public void defense(Attack attack);
}
갑옷에 관련된 클래스를 구현
[Armor.java]
package com.bkjeon.chain_of_responsibility.example2;
public class Armor implements Defense {
private Defense nextDefense;
private int def;
public Armor() {
}
public Armor(int def) {
this.def = def;
}
public void setDef(int def) {
this.def = def;
}
@Override
public void defense(Attack attack) {
// proccess 처리 완료에 상관없이 nextDefense를 무조건 호출해준다.
proccess(attack);
if (nextDefense != null) {
nextDefense.defense(attack);
}
}
private void proccess(Attack attack) {
int amount = attack.getAmount();
amount -= def;
attack.setAmount(amount);
}
public void setNextDefense(Defense nextDefense) {
this.nextDefense = nextDefense;
}
}
메인 클래스를 구현
[Main.java]
package com.bkjeon.chain_of_responsibility.example2;
public class Main {
public static void main(String[] args) {
Attack attack = new Attack(100);
Armor armor1 = new Armor(10);
Armor armor2 = new Armor(15);
armor1.setNextDefense(armor2);
armor1.defense(attack);
System.out.println(attack.getAmount());
}
}
실행결과
75
- 책임 사슬 패턴은 하나의 객체만 책임을 지는게 아니고 여러 객체가 책임을 다 같이 지어도 된다.
- 동적으로 구현할 수 있다.
[Main.java]package com.bkjeon.chain_of_responsibility.example2; public class Main { public static void main(String[] args) { Attack attack = new Attack(100); Armor armor1 = new Armor(10); Armor armor2 = new Armor(15); armor1.setNextDefense(armor2); // 첫번째 공격 armor1.defense(attack); System.out.println(attack.getAmount()); /** * Point2 */ Defense defense = new Defense() { @Override public void defense(Attack attack) { int amount = attack.getAmount(); attack.setAmount(amount -= 50); } }; /** * 동적으로도 책임사슬에 추가 할 수도 있다. */ // 게임 도중에 추가 착용 armor2.setNextDefense(defense); // 추가 착용하고 다시 공격을 당한다. attack.setAmount(100); // 두번째 공격 armor1.defense(attack); System.out.println(attack.getAmount()); } }
// 실행결과 75 25
반응형
'Java & Kotlin > Java' 카테고리의 다른 글
[Design Pattern] Observer Pattern (0) | 2020.01.05 |
---|---|
[Design Pattern] Facade Pattern (0) | 2020.01.04 |
[Design Pattern] Visitor Pattern (0) | 2020.01.01 |
[Design Pattern] Decorator Pattern (0) | 2019.12.28 |
yyyy-MM-dd 형태의 날짜 조회 방법 (0) | 2019.12.26 |
Comments