2017-03-26 1 views
3

여러 장소에서 오류 메시지와 성공 메시지를 생성 할 수있는 프로세스가 있으므로 한 클래스로 모두 추적 한 다음 프로세스가 끝나면 여러 가지 '유형'별로 메시지를 그룹화합니다. 이 라인을 따라 뭔가 :제네릭을 사용하여 instanceof를 피할 수있는 방법이 있습니까?

public class Message { 
    String message; 
    public Message(String message) { 
     this.message = message; 
    } 
} 

public class ErrorMessage extends Message {}; 
public class FileErrorMessage extends ErrorMessage {}; 
public class OkMessage extends Message {}; 

등등. (명확성을 위해 파생 클래스에서 생성자를 건너 뜁니다.) 나는 instanceof 연산자, 그러나을 사용하여 List 중에서 차별화 할 수 있습니다. 제네릭이 더 우아 할 것이라고 생각하지만, 어떻게 목록에서 차별화 할 수 있습니까?

Message<ErrorMessage> eMsg = new Message<ErrorMessage>("invalid user"); 
Message<FileErrorMessage> feMsg = new Message<FileErrorMessage>("file not found"); 

내가 사용하는 열거

다른 클래스에 대한
enum MessagType { ERROR, FILE_ERROR, OK } 

생각하지만, 나는 해결책을 마련 할 수 없었다. 감사.

+3

그들과 차별 * * *? 알 수없는 일들을하는 것처럼 일반적인 솔루션을 찾고 있다면 [방문자 패턴] (https://en.wikipedia.org/wiki/Visitor_pattern)을 사용해야합니다. 선험적으로 알려진 일을 구체적으로하고 싶다면 다형성을 사용할 수 있습니다. –

+1

"다른 클래스에서 열거 형 [...] 사용을 고려했습니다."열거 형 필드가있는 단일 클래스를 사용할 수 있습니다. 'Message'는'MessageType getType()'과'String getMessage()'와 같은 메소드를 제공 할 수 있습니다. – Izruo

+0

글쎄, 나는 하나의리스트에 그것들을 모두 추가하고 싶다. 그래서 미래에 정의 된 에러를리스트에 추가 할 수있다. 자바 예외 클래스가 내가 설명한 패턴을 따르는 것처럼 보입니다. 과정이 끝나면 한 곳으로 ErrorMessages를 보내고 다른 사람에게 OkMessages를 보내고 싶습니다. – bretter

답변

3

이 상황에서 일반적으로 할 수있는 작업은 메시지에 하위 클래스가 재정의 할 수있는 기능이 있습니다. 그런 다음 각 하위 클래스는 해당 함수가 호출 될 때 자체 동작을 수행하거나 메시지의 기본 동작을 유지할 수 있습니다. 기본값이 의미가 없으면 Message를 추상 클래스로 만들 수 있습니다.

그럼 할 수 있습니다 목록을 통해 루프 등의 작업을 수행 : 이것이 당신이 찾고 있던 무슨

for (Message m : messages) { 
    m.function(); 
} 

희망!

편집 : 아래의 코멘트에 대한 응답으로, 당신은 (구아바와) 같은 것을 할 수 있습니다

SetMultimap<Class, Message> messagesByType = HashMultimap.create(); 
for (Message m : messages) { 
    messagesByType.add(m.getClass(), m); 
} 

그런 다음 한 번에 서로 다른 종류의 일을 처리 할 수 ​​messagesByType을 통해 중첩 루프를 할 수 있습니다. 즉, 나는 초기 응답을 감안할 때, 이것을 실제로 할 필요가 없다는 것을 알지만, 이것은 당신의 질문에 답하는 것입니다.

+0

instanceof를 사용하지 않고 하나의 목록에있는 모든 메시지의 차이를 알리고 싶습니다. 물론 모든 클래스에는 getMessage() : String 메서드가 있습니다. – bretter

2

이 경우 제네릭을 사용하는 것은 나에게 적합하지 않습니다. 메시지의 유형별 차별화를 위해 상속을 사용하면 다양한 유형의 메시지가 다른 동작을하는 경우 이해가되지만 이는 사실이 아닌 것처럼 보입니다. 당신이 KISS principle를 참조 간단하게한다, 일반적으로

enum MessageType { ERROR, FILE_ERROR, OK } 

public class Message { 

    private final String message; 

    private final MessageType type; 

    public Message(String message, MessageType type) { 
     this.message = message; 
     this.type = type; 
    } 

    public MessageType getType() { 
     return this.type; 
    } 

    // getter for message 
} 

:

그래서, 난 그냥 Message 클래스의 속성으로 메시지의 유형을 가질 것이다.

편집 : 당신이 유형별로 그룹 메시지를 원하는 경우, 다음과 같이

, 당신이 그것을 할 수 있습니다

Map<MessageType, Message> messagesByType = messages.stream() 
    .collect(Collectors.groupingBy(Message::getType)); 

messages은 모든 메시지를 포함하는 List이다.

+0

흠 ... 클래스 ErrorMessage 확장 메시지 { 개인 최종 MessageType 유형 = MessageType.Error; ... ... } – bretter

+0

@bretter 내 생각에 당신은 상속을 전혀 사용하지 말아야한다는 것입니다. –

+0

글쎄, 나는 instanceof를 사용하지 않고 Exception 클래스와 같은 패턴을 요구하고 있다고 생각합니다. 그들이 목록에있을 때 떨어져. . – bretter

관련 문제