-
ch05 스트래티지 패턴25 - 2/설계패턴 2025. 10. 15. 00:20
1. 로봇 만들기
01. 설계
- Robot.java
public abstract class Robot { private String name; public Robot(String name) { this.name = name; } public String getName() { return name; } public abstract void attack(); public abstract void move(); }- TaekwonV.java
public class TaekwonV extends Robot { public TaekwonV(String name) { super(name); } @Override public void attack() { System.out.println("I have missile and attack with it"); } @Override public void move() { System.out.println("I can only walk."); } }- Atom.java
public class Atom extends Robot { public Atom(String name) { super(name); } @Override public void attack() { System.out.println("I have strong punch and attack with it."); } @Override public void move() { System.out.println("I can fly."); } }- Main.java
public class Main { public static void main(String[] args) { Robot taekwonV = new TaekwonV("TaekwonV"); Robot Atom = new Atom("Atom"); System.out.println("My name is " + taekwonV.getName()); taekwonV.attack(); taekwonV.move(); System.out.println(); System.out.println("My name is " + Atom.getName()); Atom.attack(); Atom.move(); } }- 결과

2. 문제점
01. 문제점
- 기존 로봇의 공격과 이동 방법 수정
- 아톰이 걷게만 하려면 move() 메소드 수정 -> 태권브이와 아톰의 move() 코드가 동일해지는 중복 발생
- 새 로봇을 만들어 기존 공격 또는 이동 방법 추가 및 수정 방법
02. 새로운 로봇의 추가
- 태권브이와 선가드의 attack 메소드 중복 문제

3. 해결책
01. 변화
- 이동 방식과 공격 방식이 변화

- 새 방식의 이동 및 공격이 계속 추가될 수 O, 기존 로봇이나 새 로봇이 별다른 코드 변경 없이 기능 제공 or 기존 공격이나 이동 방식을 다른 공격 or 이동 방식으로 쉽게 변경할 수 있어야 함
- 개선된 인터페이스

4. 스트래티지 패턴
01. Strategy Pattern = 전략 코드


- 전략을 쉽게 바꿀 수 있도록 해주는 디자인 패턴
-> 전략: 어떤 목적을 달성하기 위해 일을 수행하는 방식, 비즈니스 규칙, 문제를 해결하는 알고리즘 등으로 이해
- 프로그램에서 전략 실행 시 쉽게 전략을 바꿔야 할 필요O 경우 많이 발생
- 게임 캐릭터가 자신이 처한 상황에 따라 공격 or 행동하는 방식 바꾸고 싶을 때 유용
- 특정 작업을 하는 전략들을 여러 개 두고 필요할 때마다 갈아끼우는 패턴
03. 인터페이스
- 인터페이스 활용 시 구조 유지 및 호환성 있는 하위 코드의 설계 가능
- 프로그램 동작 중 동적으로 알고리즘 교체하기 위해서는 별도의 setter 메소드 구현 필요
- 스트래티지 패턴은 같은 문제를 해결하는 여러 알고리즘이 클래스 별로 캡슐화돼 있고, 필요 시 교체 가능하게 함으로써 동일 문제를 다른 알고리즘으로 해결O
04. 로봇 예제
- 코드
- Robot.java
public abstract class Robot { private String name; private MovingStrategy ms; private AttackStrategy as; public Robot(String name) { this.name = name; } public String getName() { return name; } public void attack() { as.attack(); } public void move() { ms.move(); } public void setMovingStrategy(MovingStrategy ms) { this.ms = ms; } public void setAttackStrategy(AttackStrategy as) { this.as = as; } }- TaekwonV.java
public class TaekwonV extends Robot { public TaekwonV(String name) { super(name); } }- Atom.java
public class Atom extends Robot { public Atom(String name) { super(name); } }- Sungard.java
public class Sungard extends Robot{ public Sungard(String name) { super(name); } }- MovingStrategy.java
public interface MovingStrategy { void move(); }- FlyingStrategy.java
public class FlyingStrategy implements MovingStrategy { @Override public void move() { System.out.println("I can fly."); } }- WalkingStrategy.java
public class WalkingStrategy implements MovingStrategy { @Override public void move() { System.out.println("I can Walk."); } }- AttackStrategy.java
public interface AttackStrategy { void attack(); }- MissileStrategy.java
public class MissileStrategy implements AttackStrategy { public void attack() { System.out.println("I have Missile and can attack with."); } }- PunchStrategy.java
public class PunchStrategy implements AttackStrategy { @Override public void attack() { System.out.println("I have strong Punch and attack with it."); } }- Main.java
public class Main { public static void main(String[] args) { Robot taekwonV = new TaekwonV("TaekwonV"); Robot Atom = new Atom("Atom"); Robot Sungard = new Sungard("Sungard"); System.out.println("My name is " + taekwonV.getName()); taekwonV.setMovingStrategy(new WalkingStrategy()); taekwonV.setAttackStrategy(new MissileStrategy()); taekwonV.attack(); taekwonV.move(); System.out.println(); System.out.println("My name is " + Atom.getName()); Atom.setMovingStrategy(new FlyingStrategy()); Atom.setAttackStrategy(new PunchStrategy()); Atom.attack(); Atom.move(); System.out.println(); System.out.println("My name is " + Sungard.getName()); Sungard.setMovingStrategy(new FlyingStrategy()); Sungard.setAttackStrategy(new MissileStrategy()); Sungard.attack(); Sungard.move(); } }- 결과
- 결제 방법 구현 코드
- Store.java
public class Store { private PaymentStategy paymentStategy; public void setPaymentStategy(PaymentStategy paymentStategy) { this.paymentStategy = paymentStategy; } public void counter(int amount) { paymentStategy.pay(amount); } }- PaymentStategy.java
public interface PaymentStategy { void pay(int amount); }- CashPayment.java
public class CashPayment implements PaymentStategy { public void pay(int amount) { System.out.println("현금으로 " + amount + "원 결제합니다. "); } }- NeverPayment.java
public class NeverPayment implements PaymentStategy { private String userID; private String userPwd; public NeverPayment(String userID, String userPwd) { this.userID = userID; this.userPwd = userPwd; } public void pay(int amount) { System.out.println("네이버페이로 " + amount + "원 결제합니다. "); } }- CreditCardPayment.java
public class CreditCardPayment implements PaymentStategy { private String name; private String creditCardNumber; private int CVC; public CreditCardPayment(String name, String creditCardNumber, int CVC) { this.name = name; this.creditCardNumber = creditCardNumber; this.CVC = CVC; } @Override public void pay(int amount) { System.out.println("신용카드로 " + amount +"원 결제합니다."); } }- Main.java
public class Main { public void main(String[] args) { Store store = new Store(); store.setPaymentStategy(new CashPayment()); store.counter(50000); store.setPaymentStategy(new CreditCardPayment("홍길동", "1234-5678-1234-5678", 383)); store.counter(200000); store.setPaymentStategy(new NeverPayment("garam", "1234gr")); store.counter(50000); } }- 결과

'25 - 2 > 설계패턴' 카테고리의 다른 글
ch06 싱글톤패턴 (0) 2025.10.15 [Week5] 5장 스트래티지 패턴 실습 (0) 2025.10.15 [Week4] 4장 디자인패턴 개요 실습 (0) 2025.10.14 [Week2] 2장 객체지향 원리 실습 (1) 2025.09.25 ch01 객체지향 모델링 (0) 2025.09.25