2016-12-15 2 views
0

아래와 같이 특별한 경우가 있습니다. Listener 클래스와 업 로더 클래스가 있습니다. 리스너 클래스는 네트워크를 통해 메시지를 수신하여 처리하고 그로부터 다른 작은 객체를 만듭니다.스테이트 풀 헬퍼 클래스를 사용하는 것은 나쁜 습관입니까?

public class Listener { 
    Uploader uploader; 

    Listener(String location) { 
     uploader = new Uploader(location); 
    } 

public void listen(Message msg) { 
    ProcessedObject obj = process(msg); 
    uploader.add(obj); 
} 

public void terminate() { 
    if (null != uploader) { 
     uploader.finish(); 
    } 
} 

}

업 로더 클래스는 추가 방법을 통해 하나 개의 객체를 받아, 업 로더시기를 결정한다. 이를 위해 목록을 유지 관리합니다. 또한 하나의 리스너에 특정한 위치 문자열이 있습니다. 요점은 다음과 같습니다.

/** 
* This class is not thread safe, and an object should not be shared across threads 
* 
*/ 
public class Uploader { 
    String location; 
    List<ProcessedObject> objects; 

    Uploader(String location) { 
     this.location = location; 
    } 

    void add(ProcessedObject obj) { 
     objects.add(obj); 

     if (objects.size() > PARTITION_SIZE) { 
      uploadObjects(objects); 
      objects.clear(); 
     } 
    } 

    void finish() { 
     uploadObjects(objects); 
    } 
} 

따라서 개체 수가 PARTITION_SIZE보다 큰 경우 업로드됩니다. 응용 프로그램에는 여러 개의 리스너가 있으며 각 리스너는 별도의 스레드에서 실행됩니다. 각 수신기에는 자체 업 로더 개체가 있습니다. javadoc에서이 클래스가 스레드로부터 안전하지 않다고 분명히 언급했습니다.

이제 제 질문은 좋은 습관입니까?

동료 중 일부는 이것이 좋은 습관이 아니며 업로드에 정적 방법을 사용하고 업 로더의 인스턴스를 만들지 말라고 권유합니다. 하지만 내 주장은, 청취자 클래스를 지저분 해지게 만들 것입니다. (청취자가 카운트를 유지하고, 나머지 오브젝트를 종료하기 전에 마지막에 확인하고 다시 업로드해야하기 때문에)

제 접근 방식에서는 전체 파티셔닝과 업로드 로직은 업 로더 클래스에서 사용할 수 있으므로 가독성과 유지 보수성이 향상됩니다.

제 질문은 제 접근법이 나쁜 습관입니까 (특히 업 로더가 스레드로부터 안전하지 않다고 명시하는 것도 고려해야합니다).

또한 여기에 내가하려고하는 디자인 패턴이 있습니까? 그렇다면 어느 것입니까?

편집 : 나는 틀린 질문을 제대로 받아들이지 않았다. 나는 여기에서 분할이나 업로드에 관심이 없다. 스레드 당 업 로더 클래스의 객체 하나를 만드는 방법, 정적 메서드로 상태를 유지하는 업 로더 클래스를 만드는 방법.

나머지 개체를 업로드하든, 아니면 전혀 분할해야하는지 여부는이 질문에 대한 우려가 아닙니다.

답변

0

업 로더를 보유하기 위해 전용 정적 ThreadLocal을 사용하여 두 가지 방법을 결합 할 수 있습니다.

더 큰 그림을 보면 :

내가 동료가 유효한 점을 생각합니다. 업 로더가 별도의 스레드 또는 스레드 풀에있을 수 있다고 생각하십시오. 이것은 모두 추상화되어 Listener로부터 숨겨 질 수 있습니다. 그러면 업 로더는 요소 수에 따라 충분한 작업이 있는지 또는 더 많은 요소를받지 않고 밀리 초의 설정된 지속 시간인지를 결정할 수 있습니다. 어쩌면 청취자가 플러시/마칠 수 있도록 허용해야하지만 그렇게해서는 안됩니다. 그런 요구 사항은 다른 코더에게는 문제가되지 않습니다.

+0

내가 잘못하지 않았다면, 나는 업 로더 스레드가 정기적으로 모니터링하고 업로드 할 수있는 객체의 공유 목록을 유지해야 할 것입니다. 당신이 제안하고있는 것입니까? – Kartik

+0

@Kartik 그게 가능한 구현 중 하나입니다. 또는 각 리스너 스레드는 연관된 업 로더 스레드를 가질 수 있습니다. 제 요지는 청취자에게 완전히 투명해야한다는 것입니다. –

+0

이것은 실제로 의미가 있습니다. 그러나이 경우에도 파티션을 올바르게 유지해야하는 업 로더입니까? – Kartik

0

나는이 질문을 잘못된 방식으로 생각한다고 생각합니다. 나쁜 습관인지 아닌지 물어 봅니다.

다른 방향으로 생각하십시오. 실제로 당신이 해결하려는 과제는 무엇입니까? 작업이 의미가 있습니까? 그리고 당신의 구현은 좋은가요?

해결하려는 작업은 하나씩 업로드하는 대신 업로드를 위해 몇 개의 개체를 함께 포장하는 것입니다.

업로드 횟수를 줄이는 것이 좋습니다. 하지만 업로드 비용에 따라 업로드 비용이 얼마나 달라지는 지 알 수 있습니다. 더 많은 것을 알면 내 생각은 완전히 합리적 일 수 있습니다.

이제 구현이 좋습니까? 음 ...

먼저 여러 스레드를 언급 했으므로 개체 목록에서 동기화하는 데 특히주의해야합니다.

다음으로 PARTITION_SIZE을 기다리는 것이 좋습니까? PARTITION_SIZE - 1 objects`을 (를) 가지고 있다면 어떨까요? 마지막 물건을 영원히 기다릴 수도 있고 다른 물건을 보내지 않을 수도 있습니다.

마지막으로 응용 프로그램이 다운되면 어떻게됩니까? 업로드 대기열에 게시했지만 아직 전송되지 않은 데이터는 손실됩니다. 그리고 그것은 정말로 정말로 나쁠 것입니다. 이 솔루션은 신뢰할 수 없습니다.

+0

1. 객체의 수가 PARTITION_SIZE보다 작 으면 업로드 할 기회를주기 위해 마지막에 호출 할 finish 메소드가 있습니다 – Kartik

+0

'terminate '가 호출 될 때를 보장합니까? – lexicore

+0

1. 앞서 언급 한 것처럼 업 로더 객체는 오직 하나의 스레드에서만 사용됩니다. 그 수업의 계약 그게, 내가 두 번 질문에 언급했다. 2. 개체의 수가 PARTITION_SIZE보다 작 으면 업로드 할 기회를주기 위해 마지막에 호출 할 finish 메서드가 있습니다. 3. 예,이 문제가 발생할 수 있습니다. 지정된 클래스. 업로드 할 데이터를 다시 가져올 수 있습니다. 그래서 그게 우리에게 전혀 신경 쓰지 않아요 여기에있는 질문은 정적 메서드와 업 로더 객체를 사용하는 것에 관한 것입니다. – Kartik

관련 문제