월 16,940원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결스프링 핵심 원리 - 고급편
프록시의 필요성
안녕하세요! 프록시 필요성에 대해 궁금해서 질문 합니다. 보통 아키텍처를 구현할때 client 가 있고 프론트를 거쳐서 백단(서버)쪽 으로 가기전에 프록시서버를 두잖아요? 선생님께서 말씀하신 프록시서버의 장점. 캐시, 접근제어 또는 보안 등등이 이미 '프록시서버'에서 필터링이 되는 부분인데. 굳이 자바단에서 까지 코드를 프록시를 써서 코드를 구현해야할까? 라는 생각이 듭니다. 즉슨, 강의에서 처럼 JDK 동적프록시 또는 CGLIB 과같은 것을 이용하여 프록시를 만들어서 코드 구현을 많이하나요?
- 미해결스프링 핵심 원리 - 고급편
Slf4j log 관련 오류
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 안녕하세요 영한님 항상 좋은 강의 감사드립니다. templateMethodV2 를 작성하는 과정에서 오류가 발생했습니다. 'log' has private access in 'com.example.advance.template.code.AbstractTemplate' 위와 같은 컴파일 오류인데요 제 코드는 아래와 같습니다 package com.example.advance.template;import com.example.advance.template.code.AbstractTemplate;import com.example.advance.template.code.SubclassLogic1;import com.example.advance.template.code.SubclassLogic2;import org.junit.jupiter.api.Test;public class TemplateMethodTest { @Test void templateMethodV1() { AbstractTemplate template1 = new SubclassLogic1(); template1.execute(); AbstractTemplate template2 = new SubclassLogic2(); template2.execute(); } @Test void templateMethodV2() { AbstractTemplate template = new AbstractTemplate() { @Override protected void call() { log.info("비즈니스 로직1 실행"); } }; log.info("클래스 이름1={}", template.getClass()); template.execute(); AbstractTemplate template2 = new AbstractTemplate() { @Override protected void call() { log.info("비즈니스 로직2 실행"); } }; log.info("클래스 이름2={}", template2.getClass()); template2.execute(); }} 참고로 intellij 롬복 플러그인 설치했고, build.gradle 에서 아래 코드도 추가되어 있는 상태입니다. testCompileOnly 'org.projectlombok:lombok'testAnnotationProcessor 'org.projectlombok:lombok'
- 미해결스프링 핵심 원리 - 고급편
질문있습니다.. 리플렉션 강의 설명중 람다를 사용하는 상황에 대해
[질문 내용]안녕하세요. 강의 잘 듣고있습니다~~ 다름아니라 리플랙션 강의 내용중 람다를 사용해서 공통화하는것도 가능하다 하셨는데요, 람다의 어떤 특징때문에 이루어 지는지 궁금합니다. 나름대로 생각해봤는데 함수형프로그래밍 (매개변수에 함수로직을 넣을수있는)개념을 써서 공통화 시키는게 맞는지 궁금합니다. 또는 리플랙션 처럼 람다 역시 런타임에 동적으로 클래스를 정의되고 그 인스턴스를 생성해서 반환하는 특성을 의미하신건가요? 질문이 어려우실수도 있는데 실마리라도 주시면 감사하겠습니다. ^^ ================= 답을 찾은것 같습니다. 혹시 저와 같은 궁금증을 가진분을 위해 남겨놓겠습니다.
- 미해결스프링 핵심 원리 - 고급편
안녕하세요 쓰레드에 대해 질문 드립니다.
쓰레드 로컬에 대해 설명해 주셨는데. 흔히 사용되는 스프링 MVC에서 쓰레드는 컨트롤러가 호출을 받으면서 생성되고 그 스레드가 서비스 레파지토리 쭉이어지다가 다시 return을 통해 컨트롤러에서 다시 ui 단에 값을 return 하면서 쓰레드가 종료 or 반납하게 되는게 맞을까요??
- 미해결스프링 핵심 원리 - 고급편
Retry 애노테이션으로 재시도 실행결과가 좀 이상합니다.
본문에는 예외가 발생 시 Retry 애노테이션을 확인해서 request를 재시도 하는것으로 나와있는데 막상 실행 시켜보면 예외가 발생하지 않아도 Retry 프록시가 실행되는거 같아서요 먼가 잘못이해하고 있는걸까요?? 실행결과 로그는 아래와 같습니다. 2022-02-19 12:49:47.587 INFO 18976 --- [ main] hello.aop.exam.ExamTest : Started ExamTest in 3.008 seconds (JVM running for 5.288) 2022-02-19 12:49:48.363 INFO 18976 --- [ main] hello.aop.exam.ExamTest : client request i = 0 2022-02-19 12:49:48.387 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] void hello.aop.exam.ExamService.request(String) args=[data0] 2022-02-19 12:49:48.416 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] String hello.aop.exam.ExamRepository.save(String) args=[data0] 2022-02-19 12:49:48.417 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(value=4) 2022-02-19 12:49:48.417 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] try count=1/4 2022-02-19 12:49:48.428 INFO 18976 --- [ main] hello.aop.exam.ExamTest : client request i = 1 2022-02-19 12:49:48.429 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] void hello.aop.exam.ExamService.request(String) args=[data1] 2022-02-19 12:49:48.429 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] String hello.aop.exam.ExamRepository.save(String) args=[data1] 2022-02-19 12:49:48.430 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(value=4) 2022-02-19 12:49:48.430 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] try count=1/4 2022-02-19 12:49:48.430 INFO 18976 --- [ main] hello.aop.exam.ExamTest : client request i = 2 2022-02-19 12:49:48.430 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] void hello.aop.exam.ExamService.request(String) args=[data2] 2022-02-19 12:49:48.430 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] String hello.aop.exam.ExamRepository.save(String) args=[data2] 2022-02-19 12:49:48.432 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(value=4) 2022-02-19 12:49:48.432 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] try count=1/4 2022-02-19 12:49:48.432 INFO 18976 --- [ main] hello.aop.exam.ExamTest : client request i = 3 2022-02-19 12:49:48.432 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] void hello.aop.exam.ExamService.request(String) args=[data3] 2022-02-19 12:49:48.432 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] String hello.aop.exam.ExamRepository.save(String) args=[data3] 2022-02-19 12:49:48.432 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(value=4) 2022-02-19 12:49:48.433 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] try count=1/4 2022-02-19 12:49:48.433 INFO 18976 --- [ main] hello.aop.exam.ExamTest : client request i = 4 2022-02-19 12:49:48.433 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] void hello.aop.exam.ExamService.request(String) args=[data4] 2022-02-19 12:49:48.433 INFO 18976 --- [ main] hello.aop.exam.aop.TraceAspect : [trace] String hello.aop.exam.ExamRepository.save(String) args=[data4] 2022-02-19 12:49:48.433 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] String hello.aop.exam.ExamRepository.save(String) retry=@hello.aop.exam.annotation.Retry(value=4) 2022-02-19 12:49:48.433 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] try count=1/4 2022-02-19 12:49:48.433 INFO 18976 --- [ main] hello.aop.exam.aop.RetryAspect : [retry] try count=2/4
- 미해결스프링 핵심 원리 - 고급편
다음 강의
안녕하세요 혹시 다음 강의 출시가 언제쯤 되는지 알 수 있을까요?? 기다리고 있는데 소식이 없어서.. 글을 남겨봅니다..
- 미해결스프링 핵심 원리 - 고급편
bean 이 아닌곳에 aop 적용방법
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용] aop 관련해서 공부중에 있습니다! spring aop 를 적용하기 위해선 bean 으로 등록이 되어야 spring 이 aop 를 적용시켜주는것으로 알고 있는데 혹시 bean 이 아닌곳에 aop 를 적용하기 위해선 어떻게 해야하나요??
- 미해결스프링 핵심 원리 - 고급편
빈 후처리기 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 안녕하세요 빈 life cycle을 보면 1. bean 생성 2. DI 3. BeanAware 함수 호출 4. Bean 후처리기 pre initializer 5. 생성 call back 함수 호출(post constructor -> after poperties set -> init method) 6. bean 후처리기 post init함수 호출 7. bean 객체 사용 -> 종료 callback 함수 호출 8. 자원 해제 순으로 진행 되는 걸로 알고 있습니다. 순서에서 보면 DI가 bean 후처리기 로직 실행 전에 이뤄지고 있습니다. 이렇게 되면 어떻게 proxy 객체를 DI객체로 다른 Bean객체로 주입할 수 있는지 궁금합니다
- 미해결스프링 핵심 원리 - 고급편
@target 의 정의에 대해 질문이 있습니다.
안녕하세요 강사님 이번 강의에서 언급하신 `@target 어노테이션`의 정의에 대해 제가 제대로 이해했는지 궁금하여 질문 남깁니다. @target 은 인스턴스의 모든 메서드를 조인 포인트로 적용하기 때문에, target 의 대상인 `ClassAop`어노테이션이 붙은 Child 클래스만 target 의 대상이라 생각했습니다. Child 클래스의 `인스턴스`는 Child 클래스로부터 생성된 객체만을 의미하는데, 이 객체는 Parent 로부터 상속을 받았습니다. 그래서 Child에 현재는 Parent 의 메소드가 구현 돼있지 않지만, 나중에라도 구현할 수 있기 때문에 "부모의 메서드도 @Target 의 대상이 되는 것" 이라고 이해했습니다. 결국 상속의 특성으로 인해 @Target 이 부모메서드에도 적용되는 것인가요? 좋은 강의 만들어주셔서 늘 감사합니다!
- 미해결스프링 핵심 원리 - 고급편
advisor 싱글톤 관리
안녕하세요. 좋은강의 감사드리며 항상 잘 보고 있습니다. 혹시 '스프링이 지원하는 프록시' -> 프록시 팩토리 적용1 에서 getAdvisor()를 스프링 빈으로 등록하지 않은 특별한 이유가 있나요???
- 미해결스프링 핵심 원리 - 고급편
이런 경우에 @RequestScope를 사용하면 어떨까요?
안녕하세요. 초보개발자 명아주입니다! 계속 싱글톤을 강조하면서 말씀해주셔서 이런 문제가 예상되었고 저는 해결책으로 @RequestScope를 이용해서 LogTrace Bean 자체를 request 마다 생성하도록 하는 방법을 생각했었습니다. 실제 테스트해본 결과, 의도한 대로 동작하는 것도 확인하긴 했습니다. 아직 경험이 부족하여 어떤 장단점이 있을지 모르겠어서 이렇게 질문작성하고 마저 다음 강의를 들으러 가겠습니다! 다음 강의에서 그 답이 나올지도 모르겠다는 생각이 들긴 하네요. 감사합니다!
- 미해결스프링 핵심 원리 - 고급편
strategy강의 소스받을수 있나요.
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? . 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 아니요3. 질문 잘하기 메뉴얼을 읽어보셨나요? 아니요[질문 내용] 전략패턴 관련 strategy강의 소스받을수 있나요. 전략패턴
- 미해결스프링 핵심 원리 - 고급편
JPA 에선 왜 기본생성자가 필요한가요?
안녕하세요. JPA 도 프록시로 인해서 기본생성자가 필요하다는 점이 생각나서 보았더니 리플레션을 통해서 생성하기 때문에 기본생성자가 필요한 것으로 보였습니다. 추측 근거: org.hibernate.bytecode.internal.javassist.FastClass.newInstance(int index, Object[] args) 메소드를 참고하였습니다. 근데 왜 `objenesis` 를 사용하면 되는데, JPA 에선 왜 POJO 스타일의 리플렉션을 사용하는지 궁금합니다.. JPA 강의에서 질문을 올려야 할지 이곳에서 올려야 할지 고민하다가 이곳에서 질문을 남깁니다.감사합니다.
- 미해결스프링 핵심 원리 - 고급편
안녕하세요 질문있습니다..v3,v4,v5
안녕하세요, 좋은강의 감사합니다. 벌써 몇개째 듣는지 모르겠네요 충분한 값어치 이상의 강의 감사드립니다.ㅎㅎ(영한님꺼 1개인가 2개빼고 전부 구입완료)..ㅎ 영한님 스타일은 항상 태초의?코드를 작성 후 버전을 올리면서 순차적으로 이렇게 이렇게 되서 결국은 이런식 이러한 강의 스타일이라 알고있습니다. 다름아니라 현재 프로젝트는 v2에서 정리단계로 넘어간후 로컬쓰레드로 넘어가는데 커리큘럼을 보니, aop쪽에서 로그를 만질껏 같긴한데 v3,v4, v5 - 에 해당하는 목차를 현재 목차를 만드신 스타일로 보면 3개정도 빼실것같은데..없는것 같아 "누락"인지, 혹은 뒷부분에서 계속 진행되는지 궁금해서 글 남겼습니다. 해당 강의 마지막 부분에서 다음시간에는 이러이러한 문제점을 개선하신다는 말을 듣고 v3,,v4,,v5,,식으로 나와야할 목차같은데 없어서 그러합니다..
- 해결됨스프링 핵심 원리 - 고급편
이번 예제에서 Config 클래스에 @Configuration 을 적용하니, Proxy 래핑/등록이 안되는것 같습니다.
강사님 안녕하세요.저는 지금 예제 구현시 의도와 다르게 약간 틀린 설정으로 생긴예상밖의 결과로 약간 혼동을 겪고있습니다. 이유는 @Configuration 을 실수로 붙였더니, 아래와 같이Proxy 가 적용되지 않은 결과가 나옵니다. Config 클래스에 아래와 같이 @Configuration 선언시 @Configurationstatic class Config { ... ...} child.childMethod(); 실행 후 로그 메세지: child Proxy=class ...AtTargetAtWithinTest$Child(Proxy 적용이 안된 스프링 빈 출력) child.parentMethod(); Parent 는 프록시 처리가 되지 않아 출력되지 않음 관례처럼 사용해오던 @Configuration 을 지우니 강의 예제결과처럼 정상으로 나옵니다.(@Import 를 통해 Config 추가 상태) Aspect 를 빈으로 등록해도 Proxy 변환이 안되는 이 상황이 이해가 되지 않아 부득이하게 질문을 남기게 되었습니다. 질문입니다. 예전 강의에서 @Configuration 은 등록되는 빈 을 대상으로 싱글톤 후처리를 위해 선언되는 것이라 알고있었습니다.( CGLIB 을 통해 프록시 후처리), 그래서 Aspect 가 당연히 적용될 줄 알았는데 @Configuration 을 붙이니,Proxy 처리가 되지 않더라구요. 아래는 두가지 결과 입니다. @Configration Config @Import(Config.class) @Configuration 선언 시, Proxy 후처리가 되지 않는 기묘한 현상에 대한 이해가 잘 되지 않습니다.이런 이유로 Config 클래스에 @Configuration 을 쓰지않고, @Import 로 추가하신 이유가 궁금합니다. 읽어주셔서 감사드립니다.
- 미해결스프링 핵심 원리 - 고급편
여러 개의 빈 후처리기를 등록하면??
안녕하세요. 최종 질문은 마지막 문단에 하였습니다. [빈 후처리기 - 예제코드2] 강의 관련 질문드립니다. 빈 후처리기 자체가 스프링 빈으로 등록이 가능한데, 예제에서 나오는 AtoBPostProcessor 이외에 제가 임의로 C클래스를 작성하고 BtoCPostProcessor 후처리기를 빈으로 등록해봤습니다. 그리고 컨테이너에 1) AtoBPostProcessor 2) BtoCPostProcessor 순서대로 빈을 등록하였습니다. 테스트 코드에서는 A 타입의 빈을 찾고 C 타입으로 캐스팅하여 c.helloC()를 실행한 결과 문제없이 동작하였습니다. 그리고 빈 후처리기 동작 순서또한 빈 후처리 등록 순서와 같았습니다. 이번에는 컨테이너에 등록할 때, 1) BtoCPostProcessor 2) AtoBPostProcessor 순서대로 등록하였더니, 오류가 발생하였습니다. 위에서 말씀드린 것처럼 컨테이너에 빈 후처리기를 빈으로 등록한 순서대로 후처리기를 통과(?)하는 것 같습니다. 질문은 1) 빈 후처리기 순서를 조작할 수 없는지? (그럴 필요는 있는지?) 2) 연쇄적(?)으로 빈후처리기를 등록하는 일이 있는지? => 즉, 첫 번째 후처리기의 결과에 따라 그 다음 후처리기를 호출할 필요가 있는지, (실무에서 여러 개의 빈 후처리기의 순서를 제어할 필요가 발생하는지) 감사합니다.
- 미해결스프링 핵심 원리 - 고급편
@Aspect 안에 여러 어드바이스 작성 시, 어드바이저는 어떻게 구성이 되나요?
안녕하세요! 항상 좋은 강의 및 답변주셔서 감사합니다. 강의를 듣고 복습하던 도중 한 가지 궁금한 부분이 있어 글을 작성하게 되었습니다. @Aspect@Slf4jpublic class AspectV2 { @Pointcut("execution(* hello.aop..*.*(..))") public void allOrder(){} // public java.lang.String hello.aop.order.OrderRepository.save(java.lang.String) @Around("allOrder()") public Object doLog1(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[log] {}", joinPoint.getSignature()); return joinPoint.proceed(); } @Around("allOrder()") public Object doLog2(ProceedingJoinPoint joinPoint) throws Throwable { log.info("[log] {}", joinPoint.getSignature()); return joinPoint.proceed(); }} 위의 코드에서 어드바이저는 총 몇개가 생기는지 궁금합니다. @Aspect가 있는 빈이 생길 경우, AutoProxyCreator가 @Aspect를 읽고 어드바이저를 작성해서 @Aspect Advisor 빌더 내부에 저장해두는 것으로 알려주셨는데요... 위의 코드가 실행되면, 어드바이저는 2개가 되는 걸까요? 아니면 1개만 되는 걸까요? 제가 이해하기로는 어드바이저는 주로 Default Advisor를 사용해서 1포인트컷 + 1어드바이저로 구성된다고 이해를 해서 2개가 생길 것으로 생각되긴 한데... 항상 좋은 강의 및 답변 해주셔서 고맙습니다. 감사합니다!
- 해결됨스프링 핵심 원리 - 고급편
예제의 자동 Advisor 구현체 를 `doLog 어드바이저`라고 불러도 되나요?
[질문 내용] 강의내용을 정리하며, AspectV1 에 작성된 코드를 `git commit` 하려고 보니어드바이저 긴 어드바이저 인데, 이름을 어떻게 붙여야 될지 난감했습니다. 난감했던 이유 `Around 어드바이저`..?: @Around 는 Pointcut 을 뜻하므로, 명칭에 맞지않다고 생각합니다. `AspectV1 어드바이저`..?: 다수의 어드바이저가 Aspect클래스 내부에 생성 될수 있어, 맞지않은 표현이라 생각합니다. 그래서 생각해본 것은 이렇습니다. "AspectV1 의 `doLog 어드바이저` 구현" 질문입니다어드바이저가 자동으로 생성된다해도, 고유한 이름을 갖고 있을텐데, 지금에선 알 방법이 없어, 추측해봤습니다.정확한 네이밍 규칙에 따르는 이름이 있다면 알려주세요.이 부분에 대해 질문을 해야될지 고민했지만, 막상 이런것들이 확고히 정해지지 않으면 기억에 오래남지 않더라구요..제가 뭘하고있는지 정의하기위해 도움을 구합니다. 감사드립니다.
- 미해결스프링 핵심 원리 - 고급편
ThreadLocal 참조 질문 드립니다.
안녕하세요. ThreadLocal에 저장한 데이터를 여러 장소에서 참조할 수 있는지 문의드립니다. 예를 들어 controller -> service -> dao 로 구성된 소스의 controller에서 ThreadLocal <String> a = new ThreadLocal(); a.set("abcd"); 위와 같이 값을 세팅 한 경우 service나 dao에서도 ThreadLocal a를 참조해서 "abcd" 값을 꺼내 사용하려면 어떻게 해야 할까요? 답변 부탁드립니다. 감사합니다.
- 미해결스프링 핵심 원리 - 고급편
상속과 위임 관계, 강의 내용과 관련해서 궁금한 내용이 있습니다.
안녕하세요. 항상 좋은 답변, 강의 해주셔서 감사합니다. 이번에는 상속과 위임 관계에 대해서 여쭤보고 싶은 것이 있어 글을 적게 되었습니다. 이번 강의에서는 추상 클래스를 상속 받는 형태로 구현을 했는데, '상속'을 받았기 때문에 부모 클래스의 변경에서 자유로울 수 없다고 하셨습니다. 이 부분까지는 이해가 갑니다! 왜냐하면 부모 클래스에서 변경된 부분이 있다면, 필요하다면 자식 클래스에서 구현을 해줘야 하는 것으로 이해하고 있기 때문입니다. 그런데 뒷쪽의 전략 패턴에서도(강의 듣고 왔어요!), Interface를 활용해 구현체를 만드는 형태였습니다. 크게 보면 결합이 약해졌다라고 이해를 할 수도 있겠는데... 마찬가지로 Interface에서 변경점이 있다면, 구현체에서도 변경점이 발생하는 것이 아닌가요? 예를 들어 interface에서 특정 메서드가 추가된다거나, 혹은 삭제된다거나 하면.. 구체에서 오버라이드 하지 않으면 안되는 상황일텐데요...! 영한님께서 말씀하신.. 내용을 제가 머리가 나빠서 정확히 못 받아들이는 것 같은데.. 혹시 조금만 더 풀어서 설명해주실 수 있으실까요? 질문의 요지는... 상속 관계에서 부모 클래스가 변하면 자식 클래스에 영향을 준다. 인터페이스 - 구체 관계에서 인터페이스가 변하면 구현체에 영향을 준다. 위 두 관계에서 어떻게해서 전략 패턴이 좀 더 상속의 단점을 제거할 수 있다는 말씀이신지, 궁금합니다! 항상 감사합니다. 좋은 하루 되세요!