2024. 12. 19. 21:01 devel/개념
ChatGPT한테 배운 코딩 패턴
2주간 자료 구조랑 함수 동작 플로우가 도저히 정리 되지 않아 도움이 필요하여 chatgpt에게 상담을 요청했다.
사실 어느정도 디자인 정답은 알고 있는데 디테일하게 정리가 되지 않아 굉장히 스트레스였다.
각각 아주 강한 규칙을 8가지 정도 정리하고 디자인을 맡겼는데 웬걸?
경외심을 넘어 두려움을 느꼈다.
디자인 된 코드 구조가 어거지로 된 것이 아닌지에 대해 문의를 넣었다.
그랬더니 더욱 놀라운 것은 어떠한 패턴과 유사한 구조이며 이런저런 부분의 점검을 했고 이상이 없다는 결과를 알려줬다.
나는 너무 놀랍고 무서워서 공부를 해야겠다는 생각이 들었다.
아래 코드는 그 일부이다.
의존성 주입 (Dependency Injection)
의존성 주입은 객체가 사용하는 의존성을 외부에서 주입하는 설계 패턴입니다. 이를 통해 객체는 직접 의존성을 생성하거나 관리하지 않고, 대신 필요한 의존성을 외부로부터 전달받습니다.
핵심 개념
- 객체가 필요로 하는 의존성을 생성하거나 스스로 결정하지 않고, 외부(주로 주입자)가 전달합니다.
- 객체 간의 결합도를 낮춰 더 유연하고 테스트 가능한 코드를 작성할 수 있습니다.
장점
- 결합도 감소: 객체는 구체적인 클래스에 의존하지 않고 인터페이스나 추상 클래스에 의존합니다.
- 테스트 용이성: 의존성을 Mock이나 Stub 객체로 대체할 수 있어 단위 테스트가 쉽습니다.
- 유연성 증가: 런타임에 다른 의존성을 주입할 수 있어 다양한 동작을 설정할 수 있습니다.
예제
의존성 주입 전:
#include <stdio.h>
typedef struct {
void (*send)(const char*);
} EmailService;
void sendEmail(const char* message) {
printf("Sending email: %s\n", message);
}
void notifyUser() {
EmailService service = { sendEmail }; // 직접 의존성 생성
service.send("Hello, User!");
}
int main() {
notifyUser();
return 0;
}
의존성 주입 후:
#include <stdio.h>
typedef struct {
void (*send)(const char*);
} EmailService;
void sendEmail(const char* message) {
printf("Sending email: %s\n", message);
}
void notifyUser(EmailService* service) { // 외부에서 의존성 주입
service->send("Hello, User!");
}
int main() {
EmailService service = { sendEmail };
notifyUser(&service); // 의존성 전달
return 0;
}
전략 패턴 (Strategy Pattern)
전략 패턴은 행위 디자인 패턴의 하나로, 실행할 동작(알고리즘)을 런타임에 교체할 수 있도록 설계합니다. 즉, 특정 기능을 사용하는 객체가 여러 전략(Strategy) 중 하나를 선택해서 동작하도록 합니다.
핵심 개념
- 행위를 정의하는 여러 알고리즘(전략)을 각각의 클래스에 캡슐화합니다.
- 동작을 실행할 때, 실행할 전략을 동적으로 선택하거나 교체할 수 있습니다.
장점
- 코드 중복 감소: 알고리즘을 별도의 클래스나 함수로 캡슐화하여 재사용성이 높아집니다.
- 유연성 증가: 런타임에 전략을 변경할 수 있습니다.
- Open/Closed 원칙 준수: 기존 코드를 수정하지 않고 새로운 전략을 추가할 수 있습니다.
예제
전략 패턴 사용 전:
#include <stdio.h>
void compressWithZip(const char* fileName) {
printf("Compressing %s using ZIP\n", fileName);
}
void compressWithRar(const char* fileName) {
printf("Compressing %s using RAR\n", fileName);
}
void compressFile(const char* fileName, const char* type) {
if (type == "zip") {
compressWithZip(fileName);
} else if (type == "rar") {
compressWithRar(fileName);
} else {
printf("Unsupported compression type\n");
}
}
int main() {
compressFile("example.txt", "zip");
compressFile("example.txt", "rar");
return 0;
}
전략 패턴 적용 후:
#include <stdio.h>
// 전략 인터페이스 정의
typedef struct {
void (*compress)(const char* fileName);
} CompressionStrategy;
// ZIP 전략 구현
void compressWithZip(const char* fileName) {
printf("Compressing %s using ZIP\n", fileName);
}
// RAR 전략 구현
void compressWithRar(const char* fileName) {
printf("Compressing %s using RAR\n", fileName);
}
// Context: 전략을 사용하는 객체
void compressFile(CompressionStrategy* strategy, const char* fileName) {
strategy->compress(fileName); // 주입된 전략 실행
}
int main() {
CompressionStrategy zipStrategy = { compressWithZip };
CompressionStrategy rarStrategy = { compressWithRar };
compressFile(&zipStrategy, "example.txt");
compressFile(&rarStrategy, "example.txt");
return 0;
}
의존성 주입과 전략 패턴의 관계
- 의존성 주입은 객체가 사용할 **전략(혹은 알고리즘)**을 외부에서 전달받는 방식으로 전략 패턴과 함께 사용될 수 있습니다.
- 전략 패턴은 주입된 전략 객체를 이용해 동작을 실행하므로, 의존성 주입을 활용해 구현하면 더 유연해질 수 있습니다.
결합 예제
#include <stdio.h>
typedef struct {
void (*compress)(const char* fileName);
} CompressionStrategy;
void compressWithZip(const char* fileName) {
printf("Compressing %s using ZIP\n", fileName);
}
void compressWithRar(const char* fileName) {
printf("Compressing %s using RAR\n", fileName);
}
void compressFile(CompressionStrategy* strategy, const char* fileName) {
strategy->compress(fileName); // 의존성 주입된 전략 실행
}
int main() {
CompressionStrategy zipStrategy = { compressWithZip };
CompressionStrategy rarStrategy = { compressWithRar };
compressFile(&zipStrategy, "example.txt");
compressFile(&rarStrategy, "example.txt");
return 0;
}
이처럼 의존성 주입은 객체 간 결합도를 낮추는 기법이고, 전략 패턴은 객체의 동작을 유연하게 바꾸기 위한 설계 패턴으로, 둘은 함께 사용하면 강력한 설계를 만들 수 있습니
'devel > 개념' 카테고리의 다른 글
RH850G3KH core Interrupt Handler에 대하여 (0) | 2022.10.29 |
---|---|
Renesas RH850G3KH core의 barrier에 관해 (0) | 2022.10.10 |
RH850G3KH core exception/interrupt 관련 정리 (1) | 2022.10.03 |
ARM Cortex-M Programming Guide to Memory Barrier Instructions (0) | 2018.03.25 |
아마존 리눅스 서버 최적화 튜닝 (0) | 2017.11.15 |