이 문제에 대한 내 조직의 의견 만 말할 수 있습니다. 우리 는 우리가 작업하는 모든 단일 프로젝트에 대해 모듈로 이동하는 과정에 있습니다. 우리가 구축하는 것은 기본적으로 마이크로 서비스 + 일부 클라이언트 라이브러리입니다. 마이크로 서비스의 경우 전환 modules
은 우선 순위가 낮습니다. 코드는 이미 도커 컨테이너에 격리되어 있으므로 여기에 모듈을 "추가"하는 것은 (우리에게) 그다지 중요하지 않은 것 같습니다. 이 작업은 천천히 진행되고 있지만 우선 순위가 낮습니다.
반면에 클라이언트 라이브러리는 완전히 다른 이야기입니다. 나는 우리가 때때로 가지고있는 혼란을 말할 수 없습니다. 제가 전에 싫었던 점을 한 가지 설명하겠습니다 jigsaw
. 모든 사람이 사용할 수 있도록 클라이언트에 인터페이스를 노출합니다. 자동으로 그 interface
입니다 public
- 세계에 노출. 일반적으로 내가하는 일은 package-private
클라이언트에 노출되지 않는 일부 클래스가 해당 인터페이스를 사용하는 것입니다. 나는 클라이언트가 그것을 사용하는 것을 원하지 않습니다. 좋은가요? 잘못된.
첫 번째 문제는 이러한 package-private
클래스가 커지고 더 많은 클래스를 원할 때 모든 것을 숨기는 유일한 방법 은 동일한 패키지에 클래스를 만드는 것입니다 .
package abc:
-- Usage.java
-- HelperUsage.java
-- FactoryUsage.java
....
그것이 커지면 (우리의 경우에는 그렇습니다) 그 패키지는 너무 큽니다. 별도의 패키지로 이동한다고 말씀 하셨나요? 물론 이죠,하지만 그 HelperUsage
와 FactoryUsage
있을 것입니다 public
그리고 우리는 처음부터 그것을 방지하기 위해 노력했다.
두 번째 문제 : 클라이언트의 모든 사용자 / 호출자 는 동일한 패키지 이름을 만들고 이러한 숨겨진 클래스를 확장 할 수 있습니다 . 우리에게 벌써 몇 번, 즐거운 시간이되었습니다.
modules
: 아름다운 방법으로이 문제가 해결 public
되지 않습니다 정말 public
더 이상; 지시문을 friend
통해 액세스 할 수 있습니다 exports to
. 이를 통해 코드 라이프 사이클 및 관리가 훨씬 쉬워집니다. 그리고 우리는 classpath 지옥에서 벗어납니다. 물론 maven/gradle
우리를 위해 주로 처리하지만 문제 가 발생하면 고통이 매우 현실적입니다. 다른 많은 예도있을 수 있습니다.
즉, 전환은 (여전히) 쉽지 않습니다. 우선, 팀의 모든 구성원이 정렬되어야합니다. 두 번째 장애물이 있습니다. 내가 여전히 보는 가장 큰 두 가지는 : 구체적으로 무엇을 기준으로 각 모듈을 어떻게 분리합니까? 아직 확실한 답은 없습니다. 두 번째는 split-packages
, 오 아름다운 "같은 클래스가 다른 모듈에 의해 내보내집니다"입니다. 라이브러리에서 이런 일이 발생하면 완화 할 수있는 방법이 있습니다. 하지만 이것이 외부 라이브러리라면 ... 그렇게 쉽지는 않습니다 .
jarA
및 jarB
(별도의 모듈) 에 의존 하지만 둘 다를 내 보내면 abc.def.Util
놀랄 것입니다. 하지만이를 해결하는 방법이 있습니다. 어떻게 든 고통 스럽지만 해결할 수 있습니다.
전반적으로 모듈로 마이그레이션 한 이후 (여전히 수행하고 있음) 코드가 훨씬 더 깔끔해졌습니다. 그리고 귀사가 "코드 우선"기업이라면 이것은 중요합니다. 다른 한편으로, 나는 이것이 선임 건축가들에게 "너무 비싸고" "실제 이득이없는"것으로 여겨 졌던 회사들에 참여했습니다.