+TypeScript 예제
ExportJob은 기록기를 만드는 시점과 사용하는 순서를 맡고, CsvJob·JsonJob은 어떤 기록기를 만들지 정한다. 변환 규칙을 추가하려고 공통 run()까지 복사할 필요가 없다.
interface IWriter { write(value: string): string; }
class CsvWriter implements IWriter {
write(value: string): string { return '"' + value.replaceAll('"', '""') + '"'; }
}
class JsonWriter implements IWriter {
write(value: string): string { return JSON.stringify({ value }); }
}
// 공통 실행 흐름은 생성 메서드가 반환한 약속만 사용한다.
abstract class ExportJob {
protected abstract create(): IWriter;
run(): string { return this.create().write("hello"); }
}
// 이 하위 클래스는 제품 선택만 바꾸며 실행 순서는 물려받는다.
class CsvJob extends ExportJob {
protected override create(): IWriter { return new CsvWriter(); }
}
class JsonJob extends ExportJob {
protected override create(): IWriter { return new JsonWriter(); }
}
for (const job of [new CsvJob(), new JsonJob()]) console.log(job.run());
"hello"
{"value":"hello"}
C#의 Create·Write는 create·write로 표기했다. 이 예제의 기록기는 파일에 쓰지 않고 CSV·JSON 문자열을 반환한다.