Programing

인터페이스를 별도의 패키지에 넣어야합니까?

lottogame 2020. 10. 24. 09:23
반응형

인터페이스를 별도의 패키지에 넣어야합니까?


저는 많은 구성 요소와 종속성이있는 다소 큰 프로젝트에서 작업하는 팀이 처음입니다. 모든 구성 요소에 interfaces대해 해당 구성 요소에 대한 노출 된 인터페이스가 배치 되는 패키지가 있습니다. 이것이 좋은 습관입니까?

나의 일상적인 관행은 항상 인터페이스와 구현이 동일한 패키지로 이동하는 것이 었습니다.


인터페이스와 구현을 모두 배치하는 것은 일반적인 장소이며 문제가되지 않는 것 같습니다.

예를 들어 Java API를 예로 들어 보겠습니다. 대부분의 클래스에는 동일한 패키지에 포함 된 인터페이스와 구현이 모두 있습니다.

예를 들어 java.util패키지를 살펴보십시오 .

그와 같은 인터페이스를 포함 Set, Map, List또한 구현하면서 같은 HashSet, HashMapArrayList.

또한 Javadocs는 패키지 내용을 표시 할 때 문서를 인터페이스클래스 보기 로 분리하므로 이러한 조건에서 잘 작동하도록 설계되었습니다 .

인터페이스가 엄청나게 많은 경우가 아니라면 인터페이스 전용 패키지를 갖는 것은 실제로 약간 과도 할 수 있습니다. 그러나 그렇게하기 위해 인터페이스를 자체 패키지로 분리하는 것은 나쁜 습관처럼 들립니다.

인터페이스 이름을 구현과 구별해야하는 경우 인터페이스를보다 쉽게 ​​식별 할 수 있도록 명명 규칙을 사용할 수 있습니다.

  • 인터페이스 이름 앞에 I. 이 접근 방식은 .NET 프레임 워크의 인터페이스를 사용합니다. 그것이 IList목록에 대한 인터페이스 라고 말하는 것은 상당히 쉬울 것 입니다.

  • - able접미사를 사용합니다 . 이 방법은 같은 자바 API에서 자주 볼 Comparable, Iterable그리고 Serializable몇 가지 이름을.


모든 언어에 대해 동일한 패키지에 함께 넣는 것이 좋습니다. 중요한 것은 외부 세계에 무엇이 노출되고 외부에서 어떻게 보이는지입니다. 구현이 동일한 패키지에 있는지 여부를 알거나 신경 쓰지 않을 것입니다.

이 특정 인스턴스를 살펴 보겠습니다.

하나의 패키지에 모든 공개 항목이 있고 공개적으로 노출되지 않은 다른 패키지에는 비공개 항목이있는 경우 라이브러리의 클라이언트는 하나의 패키지를 봅니다. 공개적으로 노출 된 항목이있는 패키지로 비공개 항목을 이동하지만 패키지 내에서 노출하지 않으면 클라이언트는 정확히 동일한 항목을 보게됩니다.

따라서 이것은 정당한 이유가없는 규칙의 냄새가납니다. 공개적으로 보이는 것에 영향을 미치지 않고 공개적으로 보이는 것에 기반하여 결정을 내리는 것입니다.

즉, 특정 인스턴스에서 인터페이스와 구현을 별도의 패키지로 분할하는 것이 좋은 생각 인 것 같으면 바로 진행하여 수행하십시오. 이 작업을 수행하는 이유는 패키지가 거대하거나 표준 구현 대신 링크 할 수있는 대체 구현이 있기 때문입니다.


OSGi와 같은 많은 프레임 워크에서는 거의해야합니다. 나는 이것이 항아리 수준 대신 패키지에서 느슨한 결합을 촉진한다고 생각합니다.


인터페이스를 다른 패키지에 넣는 한 가지 주장은 제품 또는 서비스 소비자에게 배포 할 수있는 'api'jar를 만드는 것이 더 쉽다는 것입니다. 인터페이스와 구현을 함께 사용하면 완벽하게 가능하지만 다른 패키지에 있으면 스크립트가 더 간단합니다.


Practical Software Engineering : A Case-Study Approach 라는 책 은 별도의 프로젝트 / 패키지에 인터페이스를 배치하는 것을지지합니다.

이 책이 말하는 PCMEF + 아키텍처는 다음과 같은 원칙을 가지고 있습니다.

  1. 하향 종속성 원칙 (DDP)
  2. 상향 알림 원칙 (UNP)
  3. NCP (Neighbor Communication Principle)
  4. 명시 적 연결 원칙 (EAP)
  5. 주기 제거 원칙 (CEP)
  6. 클래스 명명 원칙 (CNP)
  7. 지인 패키지 원칙 (APP)

원칙 # 3 및 # 7에 대한 설명은 이것이 좋은 생각 인 이유를 설명합니다.

Neighbor Communication Principle은 패키지가 인접 패키지와 만 직접 통신 할 수 있도록 요구합니다. 이 원칙은 시스템이 상호 통신하는 객체의 비압축성 네트워크로 분해되지 않도록합니다. 이 원칙을 시행하기 위해 인접하지 않은 객체 사이의 메시지 전달은 위임을 사용합니다 (9.1.5.1 절). 더 복잡한 시나리오에서는 아는 사람 패키지 (9.1.8.2 절)를 사용하여 인터페이스를 그룹화하여 먼 패키지와 관련된 협업을 지원할 수 있습니다.

지인 패키지 원칙은 이웃 커뮤니케이션 원칙의 결과입니다. 아는 사람 패키지는 메서드 호출에 대한 인수에서 구체적인 개체 대신 개체가 전달하는 인터페이스로 구성됩니다. 인터페이스는 모든 PCMEF 패키지에서 구현 될 수 있습니다. 이를 통해 인접하지 않은 패키지 간의 통신을 효과적으로 허용하면서 종속성 관리를 단일 아는 사람 패키지로 중앙 집중화 할 수 있습니다. 아는 사람 패키지의 필요성은 9.1.8.2 절에 설명되어 있으며 다음에 PCMEF 컨텍스트에서 다시 논의됩니다.

이 링크를 참조하십시오 : http://comp.mq.edu.au/books/pse/about_book/Ch9.pdf


예, 특정 구현을 게시하지 않고도 인터페이스를 게시 할 수 있기 때문에 매우 좋은 방법입니다. 즉, 외부 인터페이스를 게시 할 필요가없는 경우 구현과 동일한 패키지에 인터페이스 정의를 넣는 데 문제가 없습니다.


우리는 내가 일하는 곳에서 이것을한다 (즉, 하나의 패키지에 인터페이스를 넣고 다른 패키지에 구현). 우리가 얻을 수있는 주요 이점은 구현간에 쉽게 교체 할 수 있다는 것입니다.


Java 경험은 많지 않지만 인터페이스를 구현하는 구체적인 클래스가있는 어셈블리가 클라이언트는 웹 서비스 시나리오에서 중개인 공장이나 유선을 통해 프록시되기 때문입니다.


나는 일반적으로 인터페이스를 구현에 넣었지만 왜 그것들을 분리하고 싶은지 알 수 있습니다. 예를 들어, 누군가가 당신의 인터페이스를 기반으로 클래스를 다시 구현하고 싶었다고 가정 해보자. 그들은 단지 인터페이스보다는 당신의 구현과 함께 jar / lib / etc가 필요할 것이다. 분리 된 상태에서 "여기에 해당 인터페이스의 구현이 있습니다"라고 말하고이를 수행 할 수 있습니다. 내가 말했듯이, 내가하는 일이 아니라 일부 사람들이 왜 원하는지 알 수 있습니다.


나는 프로젝트에서 이것을하고 있으며 다음과 같은 이유로 인해 잘 작동합니다.

  • Separately packaged interfaces and implementations are for a different use case than for the various types of Map or Set. There is no reason to have a package just for trees (java.util.tree.Map, java.util.tree.Set). It is just a standard datastructure, so put it together with the other datastructures. However, if you are dealing with a puzzle game that has a really simple debug interface and a pretty production interface, as part of its front-end you might have a com.your.app.skin.debug and a com.your.app.skin.pretty. I would not put these in the same package, because they do different things and I know I would resort to some SmurfNamingConvention (DebugAttackSurface, DebugDefenceSurface, PrettyAttackSurface etc) to create some informal namespace for the two if they were in the same package.

  • My workaround for the problem of finding related interfaces and implementations that are in separate packages is to adopt a naming configuration for my packages. E.g. I can have all my interfaces in com.your.app.skin.framework, and know that other packages on the same level of the package tree are implementations. The disadvantage is that this is an unconventional convention. Honestly, I will see how good this convention is in 6 months time :)

  • I do not use this technique religiously. There are interfaces which only make sense in a particular implementation. I don't stick them in the framework package. There are some packages where it doesn't look like I'm going to create 40 different implementation classes, so I don't bother.

  • My application uses guice and has very many interfaces.

Questions of program design generally involve benefits and drawbacks and there is no one-size-fits all answer. Like why would you ever use this technique in a tiny 200-line program? It makes sense for me, given my other architectural choices, for my specific problem. :)


Put them in packages that reflect your projects. It is fine and common to put interfaces and implementations together if they're part of the same project, but if you're writing an API, then someone else would likely be choosing a package name relevant to their project.

In general, if it's for the same project, I don't see any benefit in keeping the interfaces in a separate package from their impls. If it's getting cluttered, there may be other package naming issues, irrespective of the interface arrangement.


I prefer them in the same package. Feels pointless to create a package specifically for interfaces. This is especially redundant for teams that simply love their interface prefixes and suffixes (e.g. the "I", and "Impl" for Java).

If there's a needs to publish a set of interfaces as public API, it makes more sense to keep them in an entirely separate project and create project dependencies instead. But it all boils down to preference and convenience of the situation I suppose.


I think it is important to note that for the OSGi framework, it is nicer that they are in different packages so that you can easily export a whole package while hiding the implementation packages.


There are a lot of good reasons for putting interfaces in a separate package from implementation. For example you may want to use container that supports Dependency Injection to wire up the necessary implementation(s) at run time, in which case only the interface needs to be present at build time and the implementation can be supplied at run time. Alternatively, you may want to provide multiple implementations (for example using mock implementations for testing) or multiple versions of a particular implementation at run time (for example for A/B testing, etc). For these kinds of use cases it's more convenient to package interface and implementation separately.

참고URL : https://stackoverflow.com/questions/1004980/should-interfaces-be-placed-in-a-separate-package

반응형