본문 바로가기
IT개발/design pattern

전략패턴(Strategy Pattern)

by jusyBear 2023. 12. 2.
반응형

참고

[디자인패턴] 전략 패턴 ( Strategy Pattern )

 

[디자인패턴] 전략 패턴 ( Strategy Pattern )

전략 패턴 ( Strategy Pattern )객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성하고, 유사한 행위들을 캡슐화 하는 인터페이스를 정의하여,객체의 행위를 동적으로 바꾸고 싶은 경우 직접

victorydntmd.tistory.com

정의

객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성, 유사한 행위들을 캡슐화 하는 인터페이스를 정의하여, 객체의 행위를 동적으로 바꾸고 싶은 경우 직접 행위를 수정하지 않고 전략을 바꿔주기만 함으로써 행위를 유연하게 확장하는 방법

문제의 소스

enum FavoriteWorkout {
  Running, Soccer, Gym
}

class Person {
  public name: string;
  public favoriteWorkout: FavoriteWorkout;

  constructor(name: string, favoriteWorkout: FavoriteWorkout) {
    this.name = name;
    this.favoriteWorkout = favoriteWorkout;
  }

  workout(): void {
    console.log(`${ this.name } decided to:`);
    if(this.favoriteWorkout == FavoriteWorkout.Running) {
      console.log('Go running on the park.')
    } else if (this.favoriteWorkout == FavoriteWorkout.Soccer) {
      console.log('Play soccer with friends.')
    } else if (this.favoriteWorkout  == FavoriteWorkout.Gym) {
      console.log('Go to the gym.')
    }
  }

}

// Execute
const Josh = new Person('Josh', FavoriteWorkout.Soccer)
Josh.workout() // Josh decided to: Play soccer with friends.

if문이 꼭 나쁜 것은 아니다. 하지만 나중에 만약 Running, Soccer, Gym 외의 취미 활동이 생겨서 추가 하게 된다면? 그때도 기존의 소스코드는 무엇이었더라? 분석하고 해당 부분을 발견해서 흐음 이렇게 작성해놨군 그럼 else if로 추가 해야겠다 하고 추가 할 것인가?

나중에 취미가 100개가 넘어가면 else if가 100개가 존재하게 될것이다.

이건 대단히 비효율적이고 문제가 있는 소스코드가 되는 것이다. 이러한 소스 코드를 해결 하기 위해서 우리는 디자인 패턴을 공부하고 실제 적용할 수 있어야 한다.

인터페이스 생성

// contracts.ts file
export interface FavoriteWorkout {
  begin(): void;
}

클래스 구현

sports 클래스 구현

// sports.ts file
import { FavoriteWorkout } from './contracts.ts'

export class Running implements FavoriteWorkout {
  public begin(): void {
    console.log('Go running on the park.')
  }
}

export class Soccer implements FavoriteWorkout {
  public begin(): void {
    console.log('Play soccer with friends.')
  }
}

export class Gym implements FavoriteWorkout {
  public begin(): void {
    console.log('Go to the gym.')
  }
}

Person클래스 구현

// person.ts
import { FavoriteWorkout } from './contracts.ts'

class Person {
  public name: string;
  public favoriteWorkout: FavoriteWorkout;

  constructor(name: string, favoriteWorkout: FavoriteWorkout) {
    this.name = name;
    this.favoriteWorkout = favoriteWorkout;
  }

  workout(): void {
    console.log(`${ this.name } decided to:`);
    this.favoriteWorkout.begin()
  }
}

실행

// main.ts
import { Person } from './person.ts'
import { Soccer } from './sports.ts'

// Execute
const Josh = new Person('Josh', new Soccer())
Josh.workout() // Josh decided to: Play soccer with friends.

만약 여기에 다른 스포츠를 추가하게 되면 더 이상 여러 부분을 찾고 고치고 할 필요 없이 해당 부분만 찾아가면 된다. 아래 소스코드와 같이 말이다. 내가 해준 것은 Volleyball 클래스를 추가해준거 밖에 없다.

// sports.ts file add Volleyball class
export class Volleyball implements FavoriteWorkout {
  public begin(): void {
    console.log('Play volleyball with his friends')
  }
}

//main.ts
import { Person } from './person.ts'
import { Soccer } from './sports.ts'

// Execute
const Josh = new Person('Josh', new Volleyball())
Josh.workout() // Josh decided to: Play volleyball with his friends.

이렇게 전략 패턴에 대해서 알아보았다. 이제 실제 적용을 해보는 것은 구현하면서 직접 사용을 해봐야 할 것 같다.

반응형