특정한 목표를 수행하기 위한 행동 계획
디자인 패턴 중에 하나로 객체가 할 수 있는 행위들 각각을 전략으로 만들어 놓고 사용하며, 동적으로 전략 수정이 가능한 패턴이다.
디자인 패턴: (소프트웨어)디자인 + (공통적으로 마주치는 문제를 해결하는 방법의) 패턴
예시를 보며 이해해보자.
로보는 움직이는 기능과 청소 기능이 있는 가정용 로봇이다.
로봇의 종류에는 빠르게 움직이며 설거지를 하는 것과 느리게 움직이며 바닥을 쓰는 것이 있다.
추상클래스: 클래스에 필요한 메서드을 구현하지 않고 추상 메서드로 만들어 놓은 것.
추상클래스를 사용하기 위해서는 추상클래스를 상속받아 추상 메서드를 오버라이딩을 통해 재정의 해주어야 한다.
오버라이딩: 상속에서 메서드의 기능을 재정의하는 것이다.
오버로딩: 파라미터가 다르다면, 같은 이름을 사용하는 것이 허용된다.
public abstract class Robot{
public abstract void move();
public abstract void clean();
}
class FastAndWashDishesRobot extends Robot {
public void move() {
System.out.println("빨라빨라. 나는야 날쌘 로보. ")
}
public void clean() {
System.out.println("뽀득뽀득 설거지 중");
}
}
class SlowAndSweepFloorRobot extends Robot {
public void move() {
System.out.println("천천히 천천히. 나는야 느긋한 로보 ")
}
public void clean() {
System.out.println("쓰윽쓰윽 바닥 쓰는 중");
}
}
public abstract class Robot{
public abstract void move();
public abstract void clean();
public abstract void talk(); //새로운 메서드 등장!
}
class FastAndWashDishesRobot extends Robot {
public void move() {
System.out.println("빨라빨라. 나는야 날쌘 로보. ")
}
public void clean() {
System.out.println("뽀득뽀득 설거지 중");
}
public void talk() {System.out.println("말해봐요 말말 ")} //클래스 안 코드를 수정해야 한다.
}
class SlowAndSweepFloorRobot extends Robot {
public void move() {
System.out.println("천천히 천천히. 나는야 느긋한 로보 ")
}
public void clean() {
System.out.println("쓰윽쓰윽 바닥 쓰는 중");
}
public void talk() {System.out.println("나는야 말하는 로봇")} //클래스 안 코드를 수정해야 한다.
}
OCP 원칙: 기능은 추가하되, 기존의 코드는 수정하지 않아야 한다
public interface MoveStrategy{ // 전략에 따른 인터페이스를 만듬
void move();
}
class FastMove implements MoveStrategy { // 전략을 implements함
public void move() {
System.out.println("나는야 빠른 로봇");
}
}
class SlowMove implements MoveStrategy {
public void move() {
System.out.println("느긋한 내가 좋다네~");
}
}
interface vs abstract class
부모가 여럿인 클래스를 다중상속이라고 하는데, 자바에서는 이를 금지한다.
다만, interface를 implements 하면, 다중상속처럼 사용이 가능하다.
interface는 여러개를 implements하는 것이 가능하다.
public interface MoveStrategy{ // 전략에 따른 인터페이스를 만듬
void move();
}
class FastMove implements MoveStrategy { // 전략을 implements함
public void move() {
System.out.println("나는야 빠른 로봇");
}
}
class SlowMove implements MoveStrategy {
public void move() {
System.out.println("느긋한 내가 좋다네~");
}
}
abstract class Robot{
private MoveStrategy movestrategy; //전략
public Robot(MoveStrategy movestrategy) {
this.movestrategy = movestrategy; //전략
}
public setMoveStrategy(MoveStrategy movestrategy){ // setter정의
this.movestrategy = movestrategy;
}
}
// main 클래스
public class Main{
public static void main(String[] args) {
Robot robo = new Robot(new FastMove()) // MoveStrategy로 업캐스팅된다.
robo.move(); // "나는야 빠른 로봇"
robo.setMoveStrategy(new SlowMove());
robo.move(); // "느긋한 내가 좋다네~"
}
}