오늘과 내일(?)의 TIL, 그래서 TTIL
과제는 다음과 같습니다.
- 수많은 디자인패턴 중 최소 '3가지'에 대해 조사하고 Typescript로 예시 코드를 작성해오세요.
- 복붙은 안돼요.
참고 사이트 Refactoring.Guru
작업들을 모아놓고 사용자와 커맨더를 분리한다.
// 행동패턴 - 커맨드 패턴
// 얘를 쓰는 클래스는 command 인터페이스를 따르는 것으로 간주한다.
interface Command {
execute(): void;
}
// 구체적인 작업 엑조디아1 - 뭐라도 쳐
// Search 객체에서 타이핑을 부를 수 있게 함
class TypingCommand implements Command {
constructor(private search: Search) {}
public execute() {
this.search.Typing();
}
}
// 구체적인 작업 엑조디아2 - 뭐라도 찾아
// Search 객체에서 파인딩을 부를 수 있게 함
class FindingCommand implements Command {
constructor(private search: Search) {}
public execute() {
this.search.Finding();
}
}
// 서치 클래스 (수신자 클래스)
// 실제 작업을 가지고 있다.
class Search {
public Typing() {
console.log('일단 뭐라도 쳐보는거임');
}
public Finding() {
console.log('뭐라도 일단 찾아보는거임');
}
}
// 생성자
// 커멘드 객체를 가지고 있다. 이 커맨드 객체는 execute를 부른다.
class openGoogle {
constructor(private command: Command) {}
public googling() {
this.command.execute();
}
}
// 사용예제
//수신자 만들기
const search = new Search();
// 커맨드 객체 생성
const TypingSomething = new TypingCommand(search);
const FindingSomething = new FindingCommand(search);
// 발송자 객체 생성 - 생성자로 전달
const openChrome = new openGoogle(FindingSomething);
//발송자가 메소드 호출
openChrome.googling(); // 뭐라도 일단 찾아보는거임 < 나옴
openChrom
-발송자 클래스 (invoker라고도 함)는 요청들을 시작하는 역할을 합니다. 이 클래스에는 커맨드 객체에 대한 참조를 저장하기 위한 필드가 있어야 합니다. 발송자는 요청을 수신자에게 직접 보내는 대신 해당 커맨드를 작동시킵니다. 참고로 발송자는 커맨드 객체를 생성할 책임이 없으며 일반적으로 생성자를 통해 클라이언트로부터 미리 생성된 커맨드를 받습니다.
Command
class TypingCommand,FindingCommand
class Search
https://brunch.co.kr/@eddwardpark/39 - 피그마로 직접 그리셨다고 한다...
// 생성 패턴 - 빌더 패턴
// 자동차 클래스, 부품을 저장함
class Car {
private parts: string[] = [];
addPart(part: string): void {
this.parts.push(part);
}
show(): void {
console.log(`자동차 부품: ${this.parts.join(',')}`);
}
}
// 추상클래스 자동차빌더는 부품을 조립하는 메서드 선언
abstract class CarBuilder {
abstract buildEngine(): void;
abstract buildTires(): void;
abstract getResult(): Car;
}
// 구체적인 자동차빌더 클래스는 추상클래스를 구체적으로 조립
class VolkswagenBeetle extends CarBuilder {
private car: Car = new Car();
buildEngine(): void {
this.car.addPart('예쁜 비틀에 엔진 넣음');
}
buildTires(): void {
this.car.addPart('예쁜 비틀에 예쁜 타이어도 넣음');
}
getResult(): Car {
return this.car;
}
}
// 마지막 관리자가 조립 마무리함
class CarDirector {
private builder: CarBuilder;
constructor(builder: CarBuilder) {
this.builder = builder;
}
construct(): void {
this.builder.buildEngine();
this.builder.buildTires();
}
}
// 사용예시
const PrettyBeetleBuilder = new VolkswagenBeetle();
const carDirector = new CarDirector(PrettyBeetleBuilder);
carDirector.construct();
const PrettyBeetle = PrettyBeetleBuilder.getResult();
PrettyBeetle.show();
그림이 완벽해서 설명은 생략한다.
// 구조패턴 - 어댑터 패턴
// 디자이너 클래스
class Frontend {
frontUXUI(): string {
return '프론트 할 수 있음?';
}
}
// 개발자 클래스
class Backend {
backServer(): string {
return '백엔드 할 수 있음?';
}
}
// 어댑터 클래스
class FullStack {
private frontend: Frontend;
private backend: Backend;
constructor(frontend: Frontend, backend: Backend) {
this.frontend = frontend;
this.backend = backend;
}
Project(): string[] {
const frontResult = this.frontend.frontUXUI();
const backResult = this.backend.backServer();
return [frontResult, backResult];
}
}
//사용예시
const frontend = new Frontend();
const backend = new Backend();
const fullstack = new FullStack(frontend, backend);
console.log(fullstack.Project);