반응형
서문
일반적으로 객체지향을 설명할때, 붕어빵이나 학생들로 비유하는데 , 이것이 퍽 와닿지가 않았다. 그래서 게임 LOL로 객체지향을 설명하고자 한다.
각 챔피언들: 클래스
-
롤에서 챔피언은 객체다. 하지만 롤에 등장하는 챔피언은 각각 100종류가 넘는다. 이 모든 챔피언을 하나하나 다 작성하려면 너무 복잡하고 귀찮을 것이다. 그래서 우리는 공통적인 특성을 클래스로 묶어서 재사용할 수 있다.
-
•모든 챔피언들은 공통적으로 공격력, 주문력, 방어력, 이동속도 등의 데이터를 가지고 있습니다.•또한, 평타로 공격한다., 스킬을 쓴다., 이동한다, 사망하면 못움직인다. 등의 메소드도 가집니다.
- 이런 공통적인 값들과 행동을 공유하니 클래스에서 각각 데이터와 메소드로 정의해놓고 쓸 수 있다.
챔피언: 추상 클래스
-
'챔피언'이라는 틀을 만들 때 추상 클래스로 정의하고, 각 챔피언은 이를 상속하여 자신만의 특성에 맞는 동작을 정의할 수 있다.
- 추상 클래스는 부모가 될수는 있으나 그 자체로는 객체가 될 수 없는 클래스를 말한다.
-
‘럭스’나 ‘다리우스’ 라는 챔피언은 있지만 ‘챔피언’이라는 ‘챔피언'은 없다. 따라서 그 자체가 객체는 아닌 추상클래스로 정의된다. 코드로 보면 다음과 같다.
abstract class Champion {
int attackPower;
int abilityPower;
int health;
int speed;
abstract void attack();
abstract void useSkill();
abstract void move();
abstract void die();
}
class Darius extends Champion {
@Override
void attack() {
System.out.println("Darius attacks with his axe!");
}
@Override
void useSkill() {
System.out.println("Darius uses Decimate!");
}
@Override
void move() {
System.out.println("Darius moves forward!");
}
@Override
void die() {
System.out.println("Darius dies and is respawning...");
}
}
class Lux extends Champion {
@Override
void attack() {
System.out.println("Lux attacks with her light!");
}
@Override
void useSkill() {
System.out.println("Lux uses Light Binding!");
}
@Override
void move() {
System.out.println("Lux moves around the battlefield!");
}
@Override
void die() {
System.out.println("Lux dies and is respawning...");
}
}
다형성: 챔피언마다 스킬이 다름
-
모든 챔피언들은 Q, W, E, R 스킬을 가지고 있지만, 각 스킬은 챔피언마다 다르게 동작한다.
-
그래서 각 스킬이 있다는 것은 부모 클래스인 챔피언 클래스로 받되, 각자 오버라이드 하여 다르게 사용할 수 있다.
-
이를 다형성(Polymorphism)이라고 한다. 다형성 덕분에 우리는 Champion 클래스를 사용하여 다양한 챔피언의 스킬을 실행할 수 있습니다.
Champion darius = new Darius();
Champion lux = new Lux();
darius.useSkill(); // Darius uses Decimate!
lux.useSkill(); // Lux uses Light Binding!
캡슐화: 적 캐릭터의 쿨타임이 보이지 않음
-
•챔피언들은 서로 상호작용을 하지만, 서로가 알 필요 없는 데이터들이 존재한다. 예를 들어, 체력, 마나, 레벨 등은 다른 챔피언이 볼 수 있지만, 스킬 쿨타임 같은 정보는 보이지 않는다. 이렇게 외부에서 필요한 정보만 공개하고 나머지는 숨기는 방식이 바로 캡슐화(Encapsulation)입니다.•즉, 서로 맞고 싸울 때 다른 챔피언이 쿨타임을 알 필요가 없고, 그 정보를 알지 못하도록 숨기는 것이 중요하다.•이렇게 해야 보안상으로도 좋고 서로 코드가 꼬이지 않는다. 서로 객체간 하는 행동에 관여하기 시작하면 객체로 나눈 의미가 사라진다.
class Champion {
private int health; // 외부에서 수정할 수 없도록 보호
public void takeDamage(int damage) {
this.health -= damage;
if (this.health <= 0) {
die();
}
}
private void die() {
System.out.println("Champion dies!");
}
}
상태패턴: 변신하는 챔피언들
-
상태 패턴(State Pattern)은 특정 상태에 따라 행동을 다르게 하는 패턴입니다. 예를 들어, 제이스, 앨리스, 니달리처럼 변신을 하면 스킬이나 행동이 달라지는 챔피언들이 있습니다. 이런 경우에는 상태 패턴을 사용하여 각 상태별로 다른 메소드를 적용할 수 있습니다.
- IF문을 적용하여 일일이 처리할 수도 있지만 상태패턴으로 어떤 상태인지 따라서 안의 메서드가 아예 다르게 달라지게 하는 것이다.
interface ChampionState {
void useSkill();
}
class HumanState implements ChampionState {
@Override
public void useSkill() {
System.out.println("Using human form skills!");
}
}
class AnimalState implements ChampionState {
@Override
public void useSkill() {
System.out.println("Using animal form skills!");
}
}
class Champion {
private ChampionState currentState;
public void setState(ChampionState state) {
this.currentState = state;
}
public void useSkill() {
currentState.useSkill();
}
}
전략패턴: 영구적으로 변신하는 챔피언들
-
전략 패턴(Strategy Pattern)은 알고리즘을 객체로 캡슐화하여, 실행 중에 알고리즘을 바꿀 수 있도록 하는 패턴이다. 케인처럼 변신을 통해 스킬이 달라지는 경우에 적합합니다. 이때는 상태 패턴과 비슷하지만, 상태 패턴은 객체가 자주 상태를 변경할 때 유용하고, 전략 패턴은 한 번 객체가 생성되면 그 상태가 자주 변하지 않는 경우에 사용된다.
- 예시로는 '케인'이 있을 것 같다.
interface AttackStrategy {
void attack();
}
class MeleeAttack implements AttackStrategy {
@Override
public void attack() {
System.out.println("Attack with a melee weapon!");
}
}
class RangedAttack implements AttackStrategy {
@Override
public void attack() {
System.out.println("Attack with a ranged weapon!");
}
}
class Champion {
private AttackStrategy attackStrategy;
public void setAttackStrategy(AttackStrategy strategy) {
this.attackStrategy = strategy;
}
public void attack() {
attackStrategy.attack();
}
}
데코레이터 패턴: 버프와 디버프
-
•챔피언이 특정 버프나 디버프를 받을 수 있다면, 이를 데코레이터 패턴으로 처리할 수 있습니다. 예를 들어, 장로 드래곤 버프, 레나타 부활과 같은 버프를 챔피언에게 동적으로 추가할 수 있습니다.
- 만약 데코레이터 패턴이 없다면 캐릭터가 사망할때 IF문으로 '레나타의 W버프가 걸려있는지, 사이온은 아닌지, 패시브가 있는 자크는 아닌지, 애니비아는 아닌지, 아이템 '수호천사'가 있는지 다 일일히 확인하여야 한다.
- 그렇게 if문이 반복될 수 있는 상황에서 데코레이터 패턴으로 버프와 디버프를 처리할 수 있다.
interface Champion {
void attack();
int getAttackPower();
}
class BaseChampion implements Champion {
private int attackPower = 100;
@Override
public void attack() {
System.out.println("Champion attacks!");
}
@Override
public int getAttackPower() {
return attackPower;
}
}
class ChampionWithBuff implements Champion {
private Champion wrappedChampion;
public ChampionWithBuff(Champion champion) {
this.wrappedChampion = champion;
}
@Override
public void attack() {
System.out.println("Buffed Champion attacks with extra power!");
wrappedChampion.attack();
}
@Override
public int getAttackPower() {
return wrappedChampion.getAttackPower() + 50; // Buffed attack power
}
}
인터페이스: 부모는 달라도 공통 기능을 가진 객체
-
와드, 포탑, 몬스터 등은 모두 각기 다른 부모 클래스를 가질 것이다. 하지만 공통적인 기능이 있다. 예를 들어, 평타로만 체력이 깎이는 기능이나 시야를 밝히는 기능은 와드와 포탑이 동일하다. 이처럼 전혀 다른 부모이지만, 공통된 기능을 가질 때 인터페이스를 통해 공통적으로 처리할 수 있다.
-
인터페이스는 말 그대로 '자격증'으로 인터페이스가 적용되어 있으면 누구나 해당 기능을 할 수 있다. 클래스 간의 공통된 행동을 정의하는 데 유용하다.
interface Visible {
void reveal();
}
interface Attackable {
void attack();
}
class Ward implements Visible {
@Override
public void reveal() {
System.out.println("Ward reveals an area.");
}
}
class Tower implements Attackable, Visible {
@Override
public void attack() {
System.out.println("Tower attacks with its cannon!");
}
@Override
public void reveal() {
System.out.println("Tower reveals an area.");
}
}
컴포지션: 아이템
-
•상속 대신 컴포지션(Composition)을 사용하면, 객체가 다른 객체들을 포함하여 기능을 확장할 수 있다. 예를 들어, 아이템을 컴포지션 방식으로 정의하고, 이를 챔피언 객체가 가질 수 있습니다.
- 컴포지션은 자동차안의 타이어 같은 부품 역할이다. 일방적으로 객체 안에서 교체할 수 있는 것이다.
- 그래서 롤에서는 1번부터 8번 아이템을 컴포지션으로 처리할 수 있을 것이다.
class Item {
String name;
int attackBonus;
public Item(String name, int attackBonus) {
this.name = name;
this.attackBonus = attackBonus;
}
}
class Champion {
private Item item;
public void equipItem(Item item) {
this.item = item;
}
public void
결론
OOP의 주요 내용들을 이해하기 쉽게 LOL 챔피언에 대입해서 설명하였다.
반응형
'CS 내용 요약, 지식 > Java Spring' 카테고리의 다른 글
[Java Spring]DTO란 (0) | 2024.11.23 |
---|---|
Java Annotation이란 (0) | 2024.11.23 |