JAVA - Strategy Pattern (Policy Pattern) | 자바 - 전략 패턴

Logos·2022년 4월 14일
0

Design Patterns

목록 보기
1/2

전략 패턴

에 대해서 들어보면 사실 '직관적'으로 그 의미가 와닿지 않는다. 백문이 불여일견 이고 일타라고 많이 들었다. 차근 차근 전략패턴/정책패턴 이 무엇인지 알아보자. 그리고 돌아와서 바로 다음의 정의에 대해서 생각해보자.
전략 패턴이란?
전략/비즈니스 로직 등을 정의 하고, 이를 캡슐화 한다. 그리고 이 캡슐화된 객체는 이 객체를 사용하는 사용자 객체와 독립적으로 존재하게 한다.

디자인 상황

: 우리가 지금 게임을 개발한다고 하자. 이 게임은 전략 카드 게임이다. 유저는 캐릭터를 생성할 수 있고 (기본 정보: 아이디, 종족), 그리고 이 캐릭터는 두 가지의 능력을 가진다고 하자. 하나는 '공격' 능력과 다른 하나는 '수비' 능력이다. 유저는 카드를 공격 카드 2장과 수비 카드 2장 가지고 있을 수 있고, 카드의 능력을 매턴마다 캐릭터에게 적용하면서, '공격' 또는 '수비'를 할 수 있다.

객체 특징 파익 및 분리

: 위의 '디자인 상황'에 설명 되었듯이, 우리는 위의 내용들을 객체 지향적 관점으로 분리 및 통합, 설계 등을 할 수 있다.

첫번째, 간단한 객체 대상 정리

1) 캐릭터 - 기본 정보: 아이디, 종족
2) 능력 - 공격, 수비

두번째, Runtime에 Dynamic하게 변하는 것들 찾아내기.

: 먼저, 비록 아이디와 종족은 한번 정해지면 바뀌지 않긴 하지만, 종족은 그 외모적 특징이 다르기 때문에, 각 종족별로 class를 만들 필요가 있다.
그리고, 공격 능력과 수비 능력은 카드에 따라
!!매턴마다 랜덤하고 다양하게 구현!! 될 수 있다.
(Runtime하는 동안 변경 가능)
따라서, 우리는 공격과 수비를 따로 분리해서 생각하도록 하겠다. <- 전략 패턴 적용 이유 및 대상

2) 능력 - 공격, 수비 를 버리고, 최종적으로 아래의 방식으로 객체들을 나누었다.

1) 캐릭터 - 기본 정보: 아이디, 종족
2) 종족 - 종족 특징 설명
2) 공격 - 다양한 공격 전략들.
3) 수비 - 다양한 수비 전략들.

설계

1) 캐릭터 부분 설계.

아이디, 종족을 공통 변수로 설정하고, abstract class로 만들었다. 코드 길이상 encapsulation은 하지 않았다. 이 클래스는 구체적인 "종족"들이 상속하여 사용할 것이다.


abstract class Character {
	String id;
	String race;

	Attack selectedAttack;
	Defend selectedDefend;

	private void performAttack() {
		selectedAttack.attack();
	}

	private void performDefend() {
		selectedDefend.defend();
	}

	public void displayAttack() {
		System.out.println(race);
		performAttack();
	}
	
	public void displayDefend() {
		System.out.println(race);
		performDefend();
	}
	
	public void setSelectedAttack(Attack selectedAttack) {
		this.selectedAttack = selectedAttack;
	}

	public void setSelectedDefend(Defend selectedDefend) {
		this.selectedDefend = selectedDefend;
	}
}


class Dwarf extends Character {
	public Dwarf(String id) {
		this.id = id;
		this.race = "난쟁이 포식자";
	}
}

class Knight extends Character {
	public Knight(String id) {
		this.id = id;
		this.race = "우락부락 갑옷 기사";
	}
}

class Elf extends Character {

	public Elf(String id) {
		this.id = id;
		this.race = "날씬한 미녀";
	}
	
}

2) interface: 공격 | implementation: 다양한 공격 전략들

(1) 기본 행동인 Attack interface 생성
(2) Attack을 구현한 구체적 구현체들; 아래에는 상단, 하단 공격에 대한 내용/전략들을 '텍스트'로 표현했다. 실제 게임으로 구현하면, 좀더 멋드러진 코드가 될 것이지만 말이다.

interface Attack {
	public void attack();
}

class AttackHigh implements Attack {
	@Override
	public void attack() {
		System.out.println("logic 1: 날아가기");
		System.out.println("logic 2: 칼을 들어서");
		System.out.println("logic 3: 어깨 찌르기");
	}
}

class AttackLow implements Attack {
	@Override
	public void attack() {
		System.out.println("strategy 1: 달려가기");
		System.out.println("strategy 2: 몸을 숙여서");
		System.out.println("strategy 3: 다리 베기");
	}
}

3) interface: 방어 | implementation: 다양한 방어 전략들

(1) 기본 행동인 Defend interface 생성
(2) Defend를 구현한 구체적 구현체들; 아래에는 상단, 하단 방어에 대한 내용/전략들을 '텍스트'로 표현했다.

interface Defend {
	public void defend();
}

class GuardHigh implements Defend{
	@Override
	public void defend() {
		System.out.println("logic 1: 왼발을 뒤로 빼고");
		System.out.println("logic 2: 방패를 높인뒤");
		System.out.println("logic 3: 상체 보호하기");
	}	
}

class GuardLow implements Defend{
	@Override
	public void defend() {
		System.out.println("logic 1: 몸을 숙이고");
		System.out.println("logic 2: 방패를 내린뒤");
		System.out.println("logic 3: 하체를 보호하기");
	}
}

전체 코드 요약

https://github.com/erickim0942/designPatterns/blob/main/StrategyPattern.java

profile
Fed. Software Developer

0개의 댓글