스트래티지 패턴(Strategy Pattern)?
스트래티지 패턴은 알고리즘의 그룹을 정의하고, 각 알고리즘을 캡슐화하며, 이들을 상호 교체 가능하게 만듭니다. 이를 통해 알고리즘을 사용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있습니다. Node.js에서 스트래티지 패턴은 로깅, 데이터 검증, 통신 프로토콜 등 다양한 방법에서 사용될 수 있습니다.
예제
그럼 스트래티지 패턴을 사용하여 여러 로깅 메커니즘(예: 콘솔, 파일, 원격 서버)을 지원하는 간단한 예제로 알아봅시다.
LoggerStrategy.js
class LoggerStrategy {
static toConsole(message) {
console.log(`Console: ${message}`);
}
static toFile(message) {
const fs = require('fs');
fs.appendFileSync('log.txt', `${message}\n`);
}
static toServer(message) {
const http = require('http');
const options = {
hostname: 'example.com',
port: 80,
path: '/log',
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
};
const req = http.request(options, (res) => {
console.log(`Server responded with status code: ${res.statusCode}`);
});
req.write(JSON.stringify({ message }));
req.end();
}
}
Logger.js
class Logger {
constructor(strategy = 'toConsole') {
this.strategy = LoggerStrategy[strategy];
}
log(message) {
this.strategy(message);
}
changeStrategy(newStrategy) {
this.strategy = LoggerStrategy[newStrategy];
}
}
index.js
function main() {
const logger = new Logger(); // 기본적으로 콘솔에 로깅
logger.log('Hello World');
logger.changeStrategy('toFile');
logger.log('Hello File');
logger.changeStrategy('toServer');
logger.log('Hello Server');
}
이 예제에서 main()는 애플리케이션의 시작점이 되는데 처음에는 콘솔에 로그를 출력하고, 그 다음 파일에 로그를 저장하며, 마지막으로 원격 서버에 로그를 전송합니다. 로깅 전략은 Logger 인스턴스의 changeStrategy 메소드를 통해 변경되는 형태에요.
장점
스트래티지 패턴은 소프트웨어 설계에 있어 유연성과 확장성을 크게 향상시키는 장점을 가집니다.
이 패턴을 통해 새로운 전략을 시스템의 나머지 부분을 변경하지 않고도 추가할 수 있게 되어, 기능 확장 시 기존 코드의 수정 없이 새로운 전략 클래스만 생성하면 되므로 버그와 오류의 위험을 줄이고 개발 속도를 높일 수 있습니다.
또한, 실행 시간에 전략을 교체할 수 있는 능력 덕분에 애플리케이션의 동작을 동적으로 변경할 수 있어, 사용자 요구나 실행 환경에 맞는 최적의 전략을 선택하는 유연성과 다양한 조건에 쉽게 적응하는 적응성을 제공합니다.
알고리즘의 구현이 클라이언트로부터 분리되어 있기 때문에, 전략의 재사용성이 높아지고, 시스템의 결합도가 감소하여 코드의 유지 보수가 용이해지고 시스템의 안정성이 향상됩니다.
이 모든 점들은 소프트웨어가 지속적으로 변화하고 발전해야 하는 상황에서 특히 중요하며, 개발자가 시스템의 유연성과 확장 가능성을 최대화하면서도 코드의 재사용성과 유지 보수성을 보장할 수 있도록 돕습니다.
단점
시스템 변경 없이 새로운 전략을 간편하게 추가할 수 있지만 각각의 전략을 구현하기 위해 별도의 클래스를 생성해야 합니다.
그렇게 되면 당연히 애플리케이션에서 처리해야 할 작업의 종류가 많고, 그에 따라 다양한 전략이 필요할 경우, 관리해야 할 클래스의 수가 급격히 증가하게 되어 프로젝트의 복잡성을 증가시키고, 코드의 관리 및 이해를 어렵게 만들기 때문에 이 부분을 유의 하셔야 합니다.
그래서 클래스의 증가로 인한 복잡성을 관리하기 위해, 관련 전략을 그룹화하고 공통 인터페이스를 통해 접근할 수 있도록 설계해야 합니다.
그리고 전략과 클라이언트 사이에서 데이터를 전달하는 과정에서 전략이 클라이언트로부터 많은 데이터를 필요로 하거나, 클라이언트가 전략의 결과를 다시 처리해야 할 때 오버헤드가 발생하는 상황이 벌어지게 됩니다. 그래서 필요한 데이터만 전달하거나 데이터 포맷을 최적화 하거나 전략이 필요로 하는 데이터를 캐싱하는 방법으로 통신 횟수를 줄여 오버헤드를 관리해주셔야 합니다.
스트래티지 패턴(Strategy Pattern)에서 "전략"은 특정 작업을 수행하기 위한 알고리즘 또는 방법론을 의미합니다.
오늘은 스트래티지 패턴(Strategy Pattern)에 대해 살펴보았습니다. 스트래티지 패턴(Strategy Pattern)은 여러 알고리즘, 프로세스 또는 태스크가 특정 작업에 대해 존재하고, 이들 중에서 선택해야 할 때, 애플리케이션에서 여러 변형이 필요하지만, 이러한 변형들을 조건문을 사용해 관리하는 것이 비효율적일 때, 동적으로 알고리즘을 변경하거나 설정해야 할 때 유용한 디자인 패턴입니다.
'프로그래밍(Basic) > 디자인 패턴(JS)' 카테고리의 다른 글
[바미] 미들웨어 패턴(Middleware Pattern) (0) | 2024.03.31 |
---|---|
[바미] Command 패턴 (0) | 2022.10.17 |
[바미] Compound 패턴 (1) | 2022.10.07 |
[바미] - Hooks 패턴 (2) | 2022.10.04 |
[바미] Render Props 패턴 (0) | 2022.09.25 |