2011-08-10 3 views
0

표준으로 보였으므로 지금까지 함께 해왔지만 지금은 이전 클래스를 수정하는 대신 처음부터 새로운 클래스를 작성하고 있습니다. 왜 내가 프로젝트 컨벤션을 따라야하는지 이해해야한다.모든 클래스에 대한 구현 대신 인터페이스가 생성되는 이유는 무엇입니까?

거의 모든 클래스에는 classnameable이라고하는 인터페이스가 있습니다. 코드 database.class에서는 한번도 나타나지 않지만 그 클래스를 사용하고자하는 곳에서는 databaseable.class이 표시됩니다.

인터페이스는 결코 구현되지 않았지만 표준을 유지하기 위해 가려진 클래스였습니다. 그렇다면 인터페이스가 실제 클래스처럼 사용되는 이유는 무엇입니까?

답변

9

인터페이스를 이해하려면 결코 클래스가 구현되었지만 표준을 유지하는 데는 내재되어 있지 않았습니다. 그렇다면 인터페이스가 실제 클래스 인 것처럼 사용되는 이유는 무엇입니까?

다소 혼란 스럽습니다. 인터페이스는 API를 정의하므로 다른 작성자, 모듈 또는 프로젝트의 코드 조각이 상호 작용할 수 있습니다. 예를 들어 java.util.Collections.sort()List 인터페이스를 구현하고 Comparable 인터페이스를 구현하는 객체를 포함하는 모든 것을 정렬 할 수 있습니다. 정렬 코드가 작성되었을 때 구현 클래스가 아직 존재하지 않았을지라도!

이제 불행하게도 반 패턴을 반영한 것처럼 보입니다. 모든 인터페이스는 내부 클래스의 경우에도 대부분 구현 클래스 1 개로 이루어져 있습니다.

이것은 모든 종속성을 모의 객체로 대체하여 격리 된 모든 클래스를 테스트 할 수있는 것이 필수적이라고 생각하는 TDD (Test-Driven-Development)의 지지자들에 의해 강력하게 홍보되었습니다. 이전의 조롱 프레임 워크는 인터페이스를 모의 할 수 있었기 때문에 모든 클래스를 독립적으로 테스트 할 수 있도록 모든 클래스 간 종속성은 인터페이스를 통해 이루어져야했습니다.

다행스럽게도 최신 mocking 프레임 워크는 구체적인 클래스를 모방하고 불필요한 인터페이스로 프로젝트를 오염시키지 않아도됩니다. 어떤 사람들은 어쨌든 "커플 링을 줄이기"위해해야한다고 주장하지만 IMO는 관행을 바꾸지 않겠다는 욕망을 합리화하고 있습니다.

물론 근본 주의자 TDD를 사용하지 않는다면 모든 것을위한 인터페이스를 갖고있는 좋은 이유는 없었습니다. 그러나 어떤 것들을위한 인터페이스를 갖는 것은 매우 좋은 이유였습니다.

+0

그래서 클래스를위한 인터페이스를 작성해야한다고 말하면 필적 할지라도 비교할만한 수준이 유지되어야합니다. – Skeith

+0

@ Skeith 클래스가 비교 가능해야한다면 Comparable 인터페이스를 구현해야합니다. 비교할 필요가 없다면 구현하지 않아도됩니다. 어떤 경우에도 자신 만의 인터페이스를 만들어야합니다. - Michael이 말했듯이 인터페이스를 사용하여 구현을 아직 모르고 있거나 구현이 여러 개있는 경우 특정 클래스에서 구체적인 클래스를 사용해야하는 메소드를 정의합니다. 예제를 확장하려면 :'Comparable'은'Integer','Long','String' 등을위한'sort()'메소드를 쓰지 않고 오직 하나만 사용합니다. 왜냐하면 모두'Comparable'을 구현하기 때문입니다. – Thomas

+0

@Skeit : 어려운 질문입니다. 개인적으로, 나는 일관성을 위해서만 그런 나쁜 디자인을 영속시키지 않을 것이지만 다른 사람들은 동의하지 않을 수 있습니다. 물론, 오래된 Mocking 프레임 워크를 사용하는 이유가 있다면, 새로운 클래스를 테스트하기 위해 그것을 업데이트하거나 두 번째 클래스를 도입해야합니다. 이것은 언어와 프로젝트에 익숙하지 않은 사람에게 조금 도움이 될 수 있습니다. –

2

프로젝트의 모든 단일 클래스에 대한 인터페이스가 있어도 이유가 없지만 좋은 것은 아니며이 요일에는 큰 이유가 없습니다. 예를 들어 외부 테스트 툴킷에서 필요할 때가 지나면 유산이 될 수 있습니다. 그러나 요즘은 그럴 필요가 없습니다.

느슨한 커플 링이 좋은 점이라고 들었을 것입니다. 항상 인터페이스가 아닌 구체적인 클래스에 연결해야하며,이 아이디어를 극단적으로 받아 들여야합니다.

반면에 그 중 하나만있는 경우에도 인터페이스를 정의하는 것이 좋습니다. 클래스를 작성할 때 다른 클래스 (예 : 잠재적으로 유용한) 구현이 존재할 수 있으며, 그렇다면 인터페이스를 삽입 할 것입니다. 사용하지 않는다면 아무 문제가 없지만 나중에 사용하면 나중에 시간과 번거 로움을 줄이고 리팩토링 할 수 있습니다.

1

인터페이스에 대한 클래스를 원하면 Foo 인터페이스로 이동하려면 AbstractFoo 클래스를 만드는 것이 일반적입니다. 파생 클래스가 필요에 따라이를 덮어 쓸 수 있도록 필요한 메서드를 간단하게 구현할 수 있습니다. 그러한 클래스의 예는 AbstractCollection을 참조하십시오.

작은 장점을 모두 구현할 필요가 없다는 장점이 있습니다. 이미 완료되었습니다. 단점은 다른 클래스에서 상속받을 수 없다는 것입니다. 당신은 돈을 지불하고 선택을 취합니다.

1

양호한 디자인의 표시ISomething 또는 SomethingImpl 인 경우입니다. 인터페이스 이름에 사용 방법이 나와 있어야합니다 (예 : List). 클래스 이름의 작동 방식을 설명해야합니다 (예 : ArrayList).

이름이 같으므로 사전 또는 접미사가 필요하면 구현 방법이 하나뿐이므로 분리 할 필요가 없을 수도 있음을 의미합니다. (앞으로 더 복잡한 구현이있을 것이라고 생각하는 경우 클래스 이름을 DefaultSomething 또는 SimpleSomething)

관련 문제