study-records / effective-java

이펙티브 자바를 공부하며 토론한 내용들을 정리
0 stars 0 forks source link

[아이템 01] 생성자 대신 정적 팩토리 메서드를 고려하라 #1

Closed ghojeong closed 3 years ago

ghojeong commented 3 years ago

p11 에 서비스 제공자 프레임워크(Service Provider Framework) 라는 용어가 나오는데, 대체 이게 뭐하는 걸까요? @punsoo

punsoo commented 3 years ago

이펙티브 자바 원문에 서비스 제공자 프레임 워크에 대한 설명히 간략히 나옵니다.

A service provider framework is a system in which providers implement a service, and the system makes the implementations available to clients, decoupling the clients from the implementations.

JDBC라는 서비스 제공자 프레임워크의 경우 mysql, oracle, postgre 등의 제공자가 JDBC라는 하나의 서비스를 구현하고 있는 것입니다. 여기서 제공자들이 서비스를 구현한다는 것은 서비스 제공자 프레임워크가 제공하는 규칙을 따라서 인터페이스를 만드는 것이라고 생각할 수 있겠습니다 여러 DB회사들이 Connection 인터페이스를 구현하여 JDBC 서비스 규칙을 따른 것처럼 말입니다. 이러한 구현과정은 사용자로부터 분리(decoupling)되어있기 때문에 사용자는 서비스 인터페이스(Connection)를 서비스 접근 API(DriverManager.getConnection)로부터 얻어서 편하게 사용할 수 있는 것입니다.

punsoo commented 3 years ago

p12에

제공자 인터페이스가 없다면 각 구현체를 인스턴스로 만들 때 리플렉션을 사용해야 한다

라고 되어있는데 어떤 의미인지 풀어설명해주세요!

ghojeong commented 3 years ago

p12에 제공자 인터페이스가 없다면 각 구현체를 인스턴스로 만들 때 리플렉션을 사용해야 한다라고 되어있는데 어떤 의미인지 풀어설명해주세요!

이펙티브 자바 원문을 찾아보면 위의 한글 문장은 아래의 영어 문장의 번역입니다. In the absence of a service provider interface, implementations must be instantiated reflectively (Item 65).

즉 "service provider interface" 가 없으면, "instantiated reflectively" 할 수밖에 없다는 의미이지요. "service provider interface" 라고 하면, 일반적으로 public 생성자 혹은 static factory method 를 뜻합니다. 즉 어떤 클래스가 public 생성자와 static factory method 를 둘 다 인터페이스 상으로 제공하고 있지 않을 때는, 정말로 어쩔 수 없이 리플렉션 기능을 사용해 인스턴스를 생성할 수 밖에 없다는 뜻입니다.

근데 일반적으로 인터페이스를 제공하지 않는다는 의미는, 해당 인스턴스를 직접 만들지 말라는 개발자의 의도를 갖고 있을 경우가 많으므로, 굳이 인스턴스를 만들려고 하지 않는게 좋을 것 같다는게 제 생각입니다.

punsoo commented 3 years ago

"service provider interface" 라고 하면, 일반적으로 public 생성자 혹은 static factory method 를 뜻합니다.

service provider interface는 본문에서 Driver와 같은 클래스를 지칭하는 거 같습니다. static factory method같은 경우에는 서비스 접근 api 라고 되어있네요

즉 JDBC의 경우 제가 질문했었던 문장은 Driver 가 없다면 각 구현체를 인스턴스로 만들 때 리플렉션을 사용해야 한다 가 될텐데

여전히 의문점이 생깁니다.

이펙티브 자바 01. 정적 팩토리 메소드와 서비스 제공자 인터페이스 (JDBC 예제) 리플렉션(Reflection) 위 블로그들을 참고해서 알 수 있듯이 (특히 첫번째 블로그가 좋네요) Class.forName(드라이버 클래스명)을 호출하는 부분에서 리플렉션을 이용하는 거 같거든요 즉, Driver가 있어도 리플렉션을 사용하는 거 같아서 헷갈리네요

punsoo commented 3 years ago

그리고 p12 밑에서 이어나오는 부분에

예컨대 서비스 접근 API는 공급자가 제공하는 것보다 더 풍부한 서비스 인터페이스를 클라이언트에 반환할 수 있다. 브리지 패턴이라 알려진 것이다

풍부한 서비스 인터페이스 이부분을 잘모르겠네요 먼저 브리지 패턴에 대해서는 Bridge Pattern - 브리지 패턴 블로그 링크를 살펴볼 수 있습니다. 구현부의 ConcreteImplementor 가 다양한 인터페이스가 되어 제공된다는 것일까요?

ghojeong commented 3 years ago

즉, Driver가 있어도 리플렉션을 사용하는 거 같아서 헷갈리네요

확인해보니 Driver 가 있어도 리플렉션을 사용하는 경우가 있는 것 같습니다. 하지만 일반적인 자바 개발자 입장에서, 리플렉션을 직접적으로 활용하게 되는 코드는 안티 패턴이라고 생각주세요. 리플렉션이 무엇인지는 알아야하지만, 리플렉션을 사용하는 경우와 리플렉션을 자신의 코드에서 활용하려고 하는 것은 좋지 못한 습관 같습니다.

ghojeong commented 3 years ago

service provider interface는 본문에서 Driver와 같은 클래스를 지칭하는 거 같습니다. static factory method같은 경우에는 서비스 접근 api 라고 되어있네요

"service provider interface" 와 "service access interface" 를 구분해서 읽으시려는 시도는 매우 좋은 것 같습니다. 저도 넘겨짚어서 잘못 알고 있던 부분을 덕분에 알게 되었네요. 👍

ghojeong commented 3 years ago

풍부한 서비스 인터페이스 이부분을 잘모르겠네요

그냥 단순한 service access interface 를 브릿지 패턴을 통해, 다양한 service provider interface 를 추가로 생성할 수 있다는 의미로 받아들이면 되실 것 같습니다. 이게 대체 어떻게 가능한지 이해가 안가시는 이유는 브릿지 패턴을 사용해본적이 없으셔서 인것 같습니다. 어차피 객체지향 설계를 하다보면, 브릿지 패턴을 몰라도 자연스럽게 브릿지 패턴을 언젠가 사용하게 되므로, 나중에가서 이 부분을 다시 읽으시는게 훨씬 공부 효율성이 좋을 것 같습니다.

굳이 전부 이해하려고 매달리지 마시고, service access interface, service provider interface, bridge pattern 이 세가지 키워드만 외우신 후에 다음 아이템으로 넘어가는 것도 좋을 것 같습니다.

punsoo commented 3 years ago

Using Abstractions and the Bridge Pattern in Java why-is-jdbc-a-typical-application-of-bridge-design-pattern 저도 조금 더 공부해본 자료를 남깁니다 브리지패턴으로 JDBC를 이해해보려고 할 때, Driver를 이용하는 application 측(클라이언트측)이 abstraction이라고 할 수 있고, JDBC Driver는 implement라고 할 수 있는 거 같습니다. 여전히 공급자(Mysql,Orcacle,sqlServer)가 더 풍부한 서비스 인터페이스(Connection)을 제공한다는 것이 어떻게 브리지 패턴으로 이어지는지 이해안되지만 여기까지 정리하겠습니다!

punsoo commented 3 years ago

확인해보니 Driver 가 있어도 리플렉션을 사용하는 경우가 있는 것 같습니다. 하지만 일반적인 자바 개발자 입장에서, 리플렉션을 직접적으로 활용하게 되는 코드는 안티 패턴이라고 생각주세요. 리플렉션이 무엇인지는 알아야하지만, 리플렉션을 사용하는 경우와 리플렉션을 자신의 코드에서 활용하려고 하는 것은 좋지 못한 습관 같습니다.

리플렉션을 직접적으로 활용하게 되는 코드는 안티 패턴이란 것은 잘 알아두겠습니다 그런데 제가 질문 했던 문장을 다시 생각해보니

제공자 인터페이스가 없다면 각 구현체를 인스턴스로 만들 때 리플렉션을 사용해야 한다

비록 Driver가 Class.forName으로 등록될 때 리플렉션을 사용하지만, 저 문장이 의미하는 것은 그 이후 DriverManger.getConnection으로 인스턴스를 얻을 때 리플렉션을 사용하지 않아도 된다는 뜻인거 같습니다