2012-11-13 2 views
0

리팩토링이 필요한 프로젝트가 있습니다. 약 40 개의 GUI 구성 요소가있는 Java 데스크탑 SWT/JFace 응용 프로그램으로 주요 구성 요소는 사소한 구성 요소의 수명주기를 제어합니다. 낮은 커플 링으로 좋은 모듈 형 디자인을 만들고 싶지만 매우 긴 생성자가 없어도 전역 상태를 피할 수있는 방법을 찾을 수 없습니다.난장판 생성자없이 전체 상태를 피하기

예를 들어

, 소프트웨어의 국제화에 대한 현재의 접근 방식은 같은 : 코드베이스가 성장함에 따라 열심히 종속성을 분석 할 수 있습니다 (데이터 모델) 코드를 사용 싱글에서

public class Main { 
    public static void main(String[] args) { 
     MyMessages.loadMessages(); 
    } 
} 
public class MyMessages { 
    private static ResourceBundle messages; 
    public static void loadMessages() { 
     messagesBundle = ResourceBundle.getBundle("messages", "en"); 
    } 

    public static void getMessage(String m) { 
     return messagesBundle.getString(m); 
    } 
} 

public class SomeComponent extends Component() { 
    public void init() { 
     String textboxLabel = MyMessages.getMessage("someMessage"); 
    } 
} 

다른 장소, .

대체 접근법은 MyMessages을 상태 저장하고 GUI 구성 요소의 계층 구조를 통해 인스턴스를 전달하는 것입니다. 나에게 이것은 지저분하고, 오류가 발생하기 쉬우 며, 인식 된 이익과 비교할 때 번거롭지 않다.

  • 은 본질적으로 전역 변수 무엇에 의존하지 않는다 : 다른 방법이 무엇

    가있는 방식으로이를 설계한다.

  • 종속 관계를 명시 적으로 지정합니다.
  • 긴 생성자가있는 코드를 복잡하게 만들지 않습니다.

종속성 주입 프레임 워크를 고려해야합니까, 아니면 작은 데스크톱 응용 프로그램에 과도하게 사용되지 않는 다른 접근법이 있습니까?

답변

2

종속성 주입 프레임 워크를 고려해야합니까, 아니면 작은 데스크톱 응용 프로그램에 과도하게 사용되지 않는 다른 접근법이 있습니까?

작은 데스크탑 응용 프로그램의 경우 종속성 주입 디자인 패턴을 사용하는 것이 좋지만 산업용 강도의 DI 프레임 워크는 사용하지 않는 것이 좋습니다.코드에서

는 메시지 헬퍼 클래스는 OK, 그러나 당신의 SomeComponent 클래스 친화적 인 DI 확실히되지 않습니다 :

public class SomeComponent extends Component() { 
    public void init() { 
     String textboxLabel = MyMessages.getMessage("someMessage"); 
    } 
} 

SomeComponent 지금 MyMessages 연결되어 있습니다. 기본적으로 당신의 구성 요소에 setter를 추가

public class SomeComponent extends Component() { 

    public void setTextBoxLabel(String value) { 
     // implementation depends on requirements 
    } 

    public void init() { 
     // do something with all the properties that were set 
    } 
} 

:

대신 같은 것을 사용합니다. 이것은 DI의 첫 부분입니다. 모든 클래스가 느슨하게 결합되도록하고 각 클래스는 누군가가 모든 속성을 설정하는 일을 처리 할 것이라고 믿습니다. 구성 요소가 필요로하는 모든 것이 그것으로 주입되기 때문에 글로벌 상태가 필요 없습니다.

일단 이러한 작업을 수행하면 시작 코드가 악몽이 될 것입니다. 이러한 모든 개체를 만들고 모든 속성을 설정해야하며 모든 것이 응용 프로그램에 연결되어 있어야합니다. 어느 시점에서 시작 코드를 리팩토링하고 빌더 및/또는 사용자를 위해 객체를 만드는 공장을 생성합니다.

구성 요소 중 하나가 속성 파일로 초기화되었다고 가정 해 봅시다. 특성 파일을 읽고 구성 요소를 인스턴스화하며 구성 요소 특성을 설정하고 인스턴스를 리턴하는 빌더를 작성합니다. 구성 요소는 특성 파일에 대해 아무것도 모릅니다. 단지 시작시 설정할 getters와 setters가 있습니다.

나중에 XML을 파일 형식으로 사용하기로 결정했지만 다른 앱의 경우 첫 번째 앱의 속성 파일을 계속 사용합니다. 문제 없음 - XML ​​파일을 읽고 구성 요소를 작성하는 새로운 XML 빌더를 작성하십시오. 그러나 실제 GUI 구성 요소는 초기화되는 방식과 완전히 분리되어 있기 때문에 변경되지 않습니다.

핵심은 creational design patterns을 검토하여 글로벌 상태를 피하면서 안정적으로 구성 요소를 만드는 데 도움이되는 패턴 (빌더, 공장 등)을 파악하는 것입니다.

+0

RealBundle을 주입하는 편이 좋을 것입니다. 실제 앱에는 기본 레이블 외에 툴팁 등이 있기 때문입니다. – user949300

1

전역 상태를 사용합니다. 특히보기를 다시 사용하는 경우. IMHO 의견 애플 리케이션 전체에서 무거운 사용량을 얻을 수있는 다양한 구성 요소에 대한 일종의 조회를하는 데 문제가 없습니다.

DI 프레임 워크를 사용하는 경우 암시 적으로 일종의 전역 상태를 사용할 가능성이 있습니다 (이것은 DI 프레임 워크에 따라 구현 됨). 예를 들어 Spring을 고려할 때, ApplicationContext는 다양한 빈의 구성에 따라 다양한 구성 요소를 유지하거나 구성 요소의 수명주기를 관리하는 전역 객체입니다.

글로벌 구성 요소를 갖는 것이 반드시 나쁜 것은 아닙니다. 트레이드 오프가 엄청난 생성자 시그너처이고 주위를 지나가는 참조 인 경우 전역 참조를 가져옵니다 (물론 Application 오브젝트에 넣을 수 있습니다).

+0

테스트하는 동안 모든 것이 하나 또는 두 개의 클래스에 의존한다고해서 문제가되지 않습니까? (그 길로 당신을 싫어하는 사람이 아니 었습니다.) – bcoughlan

+0

no. 느슨한 결합 원칙에 따라 구성 요소를 작성할 수 있습니다. 종속 관계가 항상 존재하지만 응용 프로그램 수준 구성 요소에 대한 느슨한 결합을 제거 할 수없는 예제를 제공합니다. – hvgotcodes

0

자바 로거 API를 사용하는 방법에 대해 ... StreamHandler 클래스를 확장하여 구성 요소로 출력 스트림을 설정할 수 있습니다. 메시지와 관련 클래스 및 메소드를 추적 할 수도 있습니다.