Whiteship's Note


EJ2E Item 19. 인터페이스는 오직 타입을 정의할 때만 사용하라

Java : 2009.01.28 12:38


참조: Effective Java 2nd Edition

어떤 클래스가 인터페이스를 구현할 때 인터페이스는 해당 클래스의 인스턴스를 참조할 수 있는 타입을 제공한다. 즉 해당 클래스 인스턴스를 가지고 고객이 무엇을 할 수 있는지 알려주는 것이다. 이 경우 이외에 다른 의도로 인터페이스를 사용하는 것은 부적절하다.

상수 인터페이스(constant interface) 안티 패턴
- 매서드 없이 상수를 표현한 static final 필드만 있다.
- 그 상수를 사용하는 클래스는 해당 인터페이스를 구현하여 상수 이름을 클래스 이름으로 구분해야 할 필요를 없앤다.(A.C B.C 대신에 A와 B가 구현하는 인터페이스 Z로 C를 올려서 Z.C 형태로 사용하게 하는 건가보네요.)
- 클래스가 내부에서 어떤 상수를 사용하는지는 구체적인 내용에 해당하는데 클래스가 상수 인터페이스를 구현하면 구체적인 내용을 밖으로 노출하게 된다.
- 차후에 해당 상수가 필요없어지더라도 바이너리 호환성을 위해 해당 인터페이스를 그대로 구현하고 있어야 한다.
- 자바 라이브러리 중에 java.io.ObjectStreamConstants는 예외다.
- 상수를 다룰 땐 해당 상수가 속하는 클래스나 인터페이스를 잘 고려해야 하며 열거형이 아닌지 보고 열거형일 경우에는 enum type 사용을 고려하라.

상수를 자주 사용할 때는 static import를 사용할 수도 있겠다.

인터페이스로는 타입을 정의해야지 상수를 표현하지 않아야 한다.
top

Write a comment.


EJ2E Item 18. 추상 클래스 보다는 인터페이스를 선호하라

Java : 2009.01.19 01:43


참조: Effective Java 2nd Edition. Item 18: Prefer interfaces to abstract classes

기존 클래스를 쉽게 수정하여 새로운 인터페이스를 구현할 수 있다.
- 인터페이스는 implements에 추가해주고 필요한 매서드를 구현하면 끝
- 하지만 새로운 추상 클래스를 만들어서 공통 로직을 상위로 올린다면, 하면 하위 클래스에는 자신에게 적당할지 안 할지도 모를 로직들을 상속받게 된다.

믹스인을 정의할 때 인터페이스가 제격이다.
- 믹스인(Mixin)이란 "원래 타입"에 어떤 부가적인 행위를 추가로 구현했다는 것을 나타내는 타입. ex) Comparable 인터페이스
- 추상 클래스는 믹스인으로 쓰기 어렵다.(단일 상속이니까)

인터페이스 계층구조가 아닌 타입 프레임워크를 구성할 수 있게 한다.

인터페이스는 Item 16에서 살펴본 wrapper class 개념을 통해 안전하고, 강력한 기능성 증진을 가져다준다.
- 추상 클래스를 사용하여 타입을 정의하면, 개발자가 기능을 추가하고 싶을 때 상속만을 써야 한다. 그 결과 클래스가 wrapper 클래스보다 점점 약해지고 깨지기 쉬워진다.

인터페이스 장점과 추상 클래스 장점을 추상 skeletal 구현체 클래스를 제공하여 얻을 수 있다.
- skeletal 인터페이스 = Abstact인터페이스, 해당 인터페이스를 구현할 때 필요한 모든 작업을 포함하고 있다.
- 개발자가 해당 인터페이스를 쉽게 구현할 수 있도록 도와준다.
- 보통은 skeletal 인터페이스를 extends 하여 만들지만, 그렇게 못할 경우에는 인터페이스를 직접 implements해도 된다.
- 인터페이스를 구현하고 그 것을 구현할 때 skeletal 클래스를 상속 받은 private inner class에 매소드 호출을 위임하는 식으로 구현할 수 있다. (simulated multiple inheritance)

인터페이스를 배포 한 뒤 그 구현체가 많아졌다면 그것을 변경하는 건 불가능에 가깝다.
- 따라서 주의해서 설계해야한다.
- 인터페이스를 정하기 전 가능한 여러 개발자가 그것을 구현해보게 하는 것이 최선이다.

top

  1. Favicon of http://naucika.pe.kr BlogIcon naucika 2009.01.19 08:12 PERM. MOD/DEL REPLY

    EJ2E 에 종속되는 내용은 아닌것 같습니다.
    그래도 실제 구현시에 인터페이스를 많이 쓰는건 사실 귀찮습니다. 그래서 설계가 무엇보다 중요하겠지만, 시간에 쫏기다 보면 유연성을 확보하기 위해 너무 많은 사전작업이 들어가 인터페이스를 잘 안쓰게 되더군요. 후회는 막급합니다만.....

    Favicon of http://whiteship.me BlogIcon 기선 2009.01.19 09:45 PERM MOD/DEL

    넹.. 저도 아직 인터페이스가 언제 어떻게 왜 필요한지 타당하게 말을 못 하겠습니다.

    모듈 간에 소통을 할 때 그 다리 역할로 사용하는 건 어느정도 이해가 되는데, 모듈 내에서(layered 아키텍처라는 전제하에) 계층 사이에서의 인터페이스가 꼭 필요한지는 조금 의문입니다.

  2. Favicon of http://www.arload.net BlogIcon arload 2009.01.19 10:59 PERM. MOD/DEL REPLY

    서로간에 장,단이 있는것 같습니다.

    실제 Framework 이나 라이브러리 설계때는 일괄적인 흐름을 주기 위해선
    Template Method를 써야 하거든요.

    그때 대안은 Abstract 입니다 . .NET Framework 의 설계자 Krzysztof Cwalina는 interface보다는 abstract를 선호하라고 애기하고 있습니다.

    to. 기선님
    layered 아키텍쳐 같은 경우는 interface 로 제어하기 보다는
    메세지 프로토콜을 결정해서 주고 받는 것이 낫습니다. layer에서 주고 받는 기능을 interface로 일일이 나열하기란 힘듭니다.

    composite message pattern 같은 것이 더 나을수 도 있습니다. google에 검색하시면 제가 등록한 도영상 강의를 보실수 있을거에요 :)
    그럼 수고하셔요 :)

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.01.19 11:19 신고 PERM MOD/DEL

    그렇군요. arload님 의견에 공감합니다.
    다 장단점이 있겠죠~

    좋은 강의 알려주셔서 감사합니다. :)

    Favicon of http://toby.epril.com BlogIcon 토비 2009.03.13 22:49 PERM MOD/DEL

    일괄적인 흐름을 주기 위해서 template을 가진 method를 만드는 것은 맞지만, 그게 Template Method Pattern으로 구현되야 할 이유는 없습니다.
    Template method에서 훅 메스도들이 아닌, 조합되어있는 협력객체들을 (주로) 인터페이스를 통해서 호출해주는 것이 훨씬 편하고 적절할 때가 많습니다.
    자바에 자주 등장하는 싱글 훅킹 메소드를 가지는 템플릿에 자주 사용되는 callback/template 스타일의 strategy 패턴의 경우도 Template Method Pattern의 상속방식 - 즉 클래스 구조의 패턴을 이용하지 않습니다.

    세상의 모든 것에는 다 장단점이 있겠지만, 원 글에서 설명한 내용은 인터페이스 사용이 적절한 예이고 그 장점이 분명합니다.

Write a comment.


냄새 나는 Switch 코드와 다형성

Java : 2006.11.30 16:02


원문 : Switch Statement code smell and polymorphism
위 글을 보면서 정리하고 있습니다.

switch-case 문을 사용한 소스코드를 보겠습니다.

위 코드를 보시면 swtich-case 문이 두 개의 메소드에서 중복이 되며 이것은 리팩토링이 필요하다는 것을 뜻합니다.

이 코드는 instanceOf 연산자를 사용해서 간추릴 수는 있지만 여전히 중복이 존재합니다. 이럴 때 다형성을 사용하려면 먼저 AbstractShape 클래스나 Shape라는 인터페이스를 만듭니다. 그리고 이를 구현 하거나 상속 받도록 구성합니다.



출처 : http://photos1.blogger.com/blogger/2606/2479/1600/ClassDiagram1.gif

위 UML 대로 코딩한 소스 코드는 다음과 같습니다.

이제 Client 코드에서는 switch 문이 사라집니다.
public class Client {
  private
Shape shape;
  ...
  public double calculateArea() {
      return
shape.getArea();
  }
  public double calculatePerimeter() {
      return
shape.getPerimeter();
  }
}

Clinet의 코드가 처음 것에 비해 굉장히 단순해 졌으며 유연해 졌습니다. 새로운 도형이 추가 되어도 그 도형이 Shape 인터페이스만 구현했다면 이 코드는 수정될 필요가 없어졌습니다.

책임이라는 관점에서 살펴본다면 처음의 Client 코드는 도형의 세부 길이 까지 너무 많은 걸 알고 었는데 반해 여기서는 도형이 뭘 할 줄 아느냐만 (메소드만) 을 이용하고 있습니다.

인터페이스와, 다형성을 사용한 swich문의 중복과 coupling을 해결한 재밌는 글이였습니다.

'Java' 카테고리의 다른 글

... 가변인수(varargs)  (2) 2006.12.11
for each 구문 사용법  (0) 2006.12.11
JUnit Reloaded  (0) 2006.12.07
I/O Stream 구성  (0) 2006.12.07
Checked Exception VS Unchecked Exception  (0) 2006.12.01
냄새 나는 Switch 코드와 다형성  (3) 2006.11.30
Map 인터페이스 살펴보기  (0) 2006.11.29
Abstract Test  (6) 2006.11.28
상속을 이용한 다형성 vs 인터페이스를 이용한 다형성  (0) 2006.11.24
Throwable 계층구조  (0) 2006.11.21
상속에 대하여...  (6) 2006.11.20
top

  1. Favicon of http://zerry82.tistory.com BlogIcon 현동규 2006.12.01 10:57 PERM. MOD/DEL REPLY

    : http://photos1.blogger.com/blogger/2606/2479/1600/ClassDiagram1.gif

    이거 에러떠여~

    Favicon of http://whiteship.tistory.com/ BlogIcon 기선 2006.12.01 12:24 PERM MOD/DEL

    흠~ 희한하네 난 잘 보이는데; 불여우에서 봐봐
    원문에 있는 그림이라서 출처를 붙일 필요는 없는것 같은데 걍 지울까;;

  2. Favicon of http://zerry82.tistory.com BlogIcon 현동규 2006.12.02 14:04 PERM. MOD/DEL REPLY

    어 보인다 -_-;;

Write a comment.


Interface

Java : 2006.10.16 00:03


Java Tutorial에 있는 interface부분을 읽으며 정리했던 내용입니다.
원래 엠파스 블러그에 정리해 두었었는데 이번 기회에 이것도 이리 옮겨오네요 :)

Interface는 다른 class들로 부터 구현될 행동들의 규약을 정의한 것이다.
Interface는 구현되어 있진 않은 메소드 정의들의 집합이다.
abstract class와의 차이점
1. abstract class는 method를 몇개 구현해 놓을 수 있지만 interface는 그렇치 않다.
2. 하나의 class는 여러 interface들을 구현할 수 있지만 (abstract) class는 하나만 상속 받을 수 있다.
3. interface는 2번과 같은 이유로 인해 class hierarchy에 속하지 않는다.
4. 전혀 상관 없는 class들도 같은 interface는 구현할 수 있다.

public
interface InterfaceName extends SupreInterfaces {
        ....
}
interface앞에 붙을 수 있는 접근 지시자는 public과 default(아무것도 안쓰는것)이다.
default의 경우 같은 패키지 안에 있는 class에서만 구현 할 수 있다.
interface는 다중 상속이 가능하다. 물론 interface만 상속 해야한다.
method들은 head부분만 쓰고 쎄미콜론으로 닫아야 한다.
자동으로 public abstarc의 키워드가 붙은것으로 간주하기에 안쓰는게 좋다.
특히 abstract는
필드도 넣을 수 있는데 암것도 안쓰면 자동으로 public static final로 간주한다.
private이나 protected 멤버는 선언할 수 없다.
그리고 멤버의 head에 transient, volatile, synchronized 키워드를 사용할 수 없다.
public class ImplClass extends JFrame implements SuperInterface1, SuperInterface2 {
      ...
}
interface를 구현하는 class에서는 여러 interface를 implements 할 수 있다.
이 것은 interface와의 이종의 계약이다. interface에 들어있는 모든 method를 구현하겠다는..
만약 이 약속을 지키지 않을 시 이 class는 abstract class가 되어야 한다.
interface type의 객체는 만들 수 없지만 변수는 만들 수 있다.
이 변수로 해당 interface를 구현한 class들의 객체를 참조 할 수 있다.
끝으로
이미 interface가 있고 그리고 그 interface를 구현한 class들이 있느 상태에서
interface에 새로운 메소드를 추가하는 가능하면 하지 말아야 한다.
그 interface를 구현한 모든 class들에서 에러가 발생할 것이다.
모든 calss들을 들려서 추가한 method를 구현해 주거나 class들을 abstract class로 만들어야 한다.
이럴바엔 차라리 새로운 interface는 만들어서 필요한 class들이 추가로 implement 하게 수정하는게 좋다.

'Java' 카테고리의 다른 글

What is Object?  (12) 2006.11.01
Agile Java 2장 연습문제 풀기  (2) 2006.10.29
Lazy Initialization 언제 사용 해야 될까요?  (9) 2006.10.28
Agile Java 1장 연습문제 풀기  (2) 2006.10.27
JUnit 3.8 과 JUnit 4의 차이  (0) 2006.10.27
Reference의 위험성  (10) 2006.10.27
다중 구현(?)  (2) 2006.10.23
Interface  (2) 2006.10.16
Lesson 3. Strings and Packages  (0) 2006.10.06
Lesson 2. Java Basics  (0) 2006.10.03
Lesson 1. Getting Started  (0) 2006.09.25
top

  1. Favicon of http://seira.pe.kr BlogIcon 세이라 2006.10.16 00:10 PERM. MOD/DEL REPLY

    간만에 읽어보는 인터페이스..
    군대에서 SCJP 딴다고 공부한 뒤로는 자바 구경을 별로 안해서..

    자바는 여전히 흥미로운 언어인거 같습니다.
    ps. 그런고로.. 저도 공부 많이 해야겠습니다 ㅡㅜ

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2006.10.16 08:43 신고 PERM MOD/DEL

    네~ :) Java 재밌지요. 사용하기 쉽다는 장점이 큰 언어인듯 하네요.(C 나 C++에 비해서요 ㅋ)

Write a comment.


Layers of Abstractions



Layers of Abstractions

Spring MVC 에플리케이션들은 여러 계층으로 나누어져있다. layer is a discrete, othogonal area of concern within an application. 여러 계층들은 에플리케이션의 추상화에 해당하며 인터페이스는 계층들간 상호작용의 규약을 제공한다. 어떤 계층들은 몇몇 다른 Layer들과 상호작용을 하지만 매우 중요한 계층은 모든 계층과 상호작용을 한다.
계층은 개념적인 경계선이고 물리적으로 떨어져 있을 필요는 없다.

A Layer is a logical abstraction within an application. A tier is best thought of as a physical deployment of the layers.


계층 구조로 생각하는 것이 에플리케이션의 전체 흐름을 개념화하는데 도움이 된다. 에플리케이션 계층들을 케잌처럼 쌓아 놓은 모습으로 보는 것이 가장 흔하고 편리한 방법이다.
Spring MVC 에플리케이션은 최소 다섯 개의 추상화된 계층을 가지고 있으며 각각은 다음과 같다.
  • user interface
  • web
  • service
  • domain object model
  • persistence

위 그림을 보면 Domain Model이 왼쪽에 세로로 서있는 것을 볼 수 있습니다. 이것은 다른 모든 계층들이 Domain Model 계층에 종속하기 때문입니다.
매우 중요한 계층인듯 합니다. 저런 경우에 AOP를 사용한다고 본 것 같은데 지금 저 계층들에 없는 tracjaction management, security같은 것은 AOP를 사용하여 뺏다고 하는데 Domain Model은 그럴만한 성격이 아닌가 보네요.

Layer Isolation


계층을 분리시키는 것은 에플리케이션을 보다 유연하고 테스트가 용이하도록 만듭니다. 이러한 분리는 계층 사이의 종속성을 최소화 함으로써 달성할 수 있습니다. 종속성 남발을 피할 수 있는 최소한 두가지 방법이 있습니다. 만약에 어떤 계층이 다른 여러 계층들에 종속하기 시작하면 다른 계층간의 상호작용을 추상화하는 새로운 계층을 만드는 것을 고려해 봅니다. 또 하나의 계층이 여러 계층들에서 사용된다면 Spring의 AOP를 사용하는 것을 어떨지 생각해 봅니다.
여기서 기억하야 할 것은 에플리케이션을 여러 계층으로 나누는 것은 decouple 된 설계를 만들어 낸다는 것입니다. 그렇게 함으로써 여러분의 에플리케이션이 보다 유연하고(확장이나 변동이 쉽고), 테스트가하기 편해집니다.

Java Interface As Layer Contract


에플리케이션의 계층을 나누는데 Java 인터페이스가 중요한 역할을 합니다. 인터페이스는 계층간의 규약이며 그들의 구현과 세부사항을 숨긴 채 계층 간의 작동이 유지될 수 있도록 합니다. 인터페이스에 의해 제공되는 low coupling의 이점에 대해서는 잘 알 고있을 것입니다. 그러나 여태까지 그러한 장점은 여태까지 인터페이스가 아닌 실제 구현된 클래스를 사용할 수 밖에 없는 상황이였기 때문에 잘 살리지 못했습니다. 하지만 Spring과 다른 DI 프레임웤을 사용한다면 가능합니다. Spring이 직접 에플리케이션의 코드 대신 객체의 생성에 대한 일을 해주기 때문입니다.
계층간의 규약을 인터페이스로 정의해두면 개발 시간을 단축시킵니다. 개발자들이 인터페이스에 맞춰 개발을 하기 때문에 그것을 구현한 코드가 작성되고 바뀌고 테스트되더라도 개발이 가능하기 떄문입니다.
계층간의 상호작용을 인터페이스로 정의해 두면 단위 테스트가 간편합니다. EasyMock과 같은 프레임웤을 사용하여 쉽게 인터페이스의 구현체를 만들어서 테스트할 수 있기 때문입니다.
인터페이스를 사용하여 계층에 접근하는 것은 컴파일 시간을 단축시키고 보다 모듈화된 개발을 가능케 합니다. Client code가 이미 사용하고 있는 것들을 재컴파일하지 않아도 새로운 클래스를 추가하거나 변경이 가능하기 때문입니다.
인터페이스를 사용하면 또한 시스템이 매우 유연해 집니다. 시스템이 시작할 때 또는 이미 실행 중일 때도 특정 구현체로 변동이 가능합니다. Client code가 인터페이스에 맞춰 컴파일 되었기 때문에 실행중에도 구현된 클래스를 바꿀수가 있습니다. 매우 동적인 시스템을 만들수가 있습니다.

여기까지 매우 간단하게 요약하자면 인터페이스를 사용하여 각 계층간의 규약을 정의한다. 인터페이스는 계층의 추상화를 제공하고 계층을 구현한 것이 다른 계층에 영향을 주지 않고 쉽게 변할 수 있도록 허용한다.

'Spring MVC > 3장 Spring MVC' 카테고리의 다른 글

Spring MVC에서 사용하는 ApplicationContext와 WebApplicationContext  (6) 2008.07.03
Service Layer  (2) 2006.12.13
Web Layer  (0) 2006.12.12
User Interface Layer  (0) 2006.10.09
Layers of Abstractions  (0) 2006.10.08
top

Write a comment.