2016-12-19 2 views
1

몇 가지 필드에서 유효성을 검사해야하는 2 개의 처리가 있습니다.입력을 확인하고 그에 따라 작업을 수행하십시오.

  • ProcessA 클래스의 경우 몇 가지 필드에서 유효성을 검사해야합니다. 이 분야에 기초하여이 수업을 검증 할 것입니다.
  • ProcessB 클래스의 경우 다른 필드에서 유효성을 검사해야합니다. 그리고 그 필드가 유효하다면이 클래스의 유효성을 검사 할 것입니다.

모두 내 프로세스 GenericRecordValidator 클래스는 해당 필드의 유효성을 검사해야 ProcessA 또는 ProcessB 여부에 따라 클래스 Validator에 지금을 통과해야한다.

  • 는 ProcessA, 나는 clientId, deviceId, payId에 확인해야합니다.
  • ProcessB의 경우 crossId, maxId, minId의 유효성을 검사해야합니다.

가 나는 ProcessA을 위해 일 할 수 있어요하지만 내 Validator 클래스 ProcessB 필드의 유효성 검사를 위해 모양을 않는 방법을 혼동입니다. 혼란은 클래스가 생성자에서 GenericRecord을 받자 마자 ProcessA 또는 ProcessB에 대한 필드의 유효성을 검사해야한다고 결정하는 것입니다. GenericRecord가 전달 된 경우 ProcessA 필드에서 유효성 검사를 수행하거나 ProcessB GenericRecord가 전달 된 경우 ProcessB 필드에서 유효성 검사를 수행합니다.

ProcessA

try { 
    GenericRecordDomainDataDecoder decoder = new GenericRecordDomainDataDecoder(config); 
    while (true) { 
    ConsumerRecords<byte[], byte[]> records = consumer.poll(1000); 
    for (ConsumerRecord<byte[], byte[]> record : records) { 
     GenericRecord payload = decoder.decode(record.value()); 
     String processName = "processA"; 
     // validation logic 
     Validator validation = new Validator(payload); 
     if(!validation.isValid()) 
      continue; 

     // some other code 
    } 
    } 
} catch (Exception ex) { 
    // logging error 
} 

ProcessB

try { 
    GenericRecordDomainDataDecoder decoder = new GenericRecordDomainDataDecoder(config); 
    while (true) { 
    ConsumerRecords<byte[], byte[]> records = consumer.poll(1000); 
    for (ConsumerRecord<byte[], byte[]> record : records) { 
     GenericRecord payload = decoder.decode(record.value()); 
     String processName = "processB"; 
     // validation logic 
     Validator validation = new Validator(payload); 
     if(!validation.isValid()) 
      continue; 

     // some other code 
    } 
    } 
} catch (Exception ex) { 
    // logging error 
} 

다음은 단지 ProcessA 확인을 위해 지금 당장 작동 내 Validator 클래스입니다. 내가 아는 또 다른 생성자를 추가했지만, 단지 내가하고자하는 것을 보여주고 싶었다. ProcessB. 그리고 나서 isValid 메서드를 호출해야합니다.이 메서드는 ProcessB의 필드가 존재하는지 여부를 알려줍니다.

public class Validator { 
    private String clientId, deviceId, payId; 

    // for ProcessA 
    public Validator(GenericRecord payload) { 
    clientId = (String) DataUtils.parseRecord(payload, "clientId"); 
    deviceId = (String) DataUtils.parseRecord(payload, "deviceId"); 
    payId = (String) DataUtils.parseRecord(payload, "payId"); 
    } 

    // for ProcessB, I know this doesn't work - just wanted to show the idea 
    public Validator(GenericRecord payload) { 
    crossId = (String) DataUtils.parseRecord(payload, "crossId"); 
    maxId = (String) DataUtils.parseRecord(payload, "maxId"); 
    minId = (String) DataUtils.parseRecord(payload, "minId"); 
    } 

    // this is what I am calling for ProcessA 
    public boolean isValid() { 
    return isValidClientIdDeviceId() && isValidPayId(); 
    } 

    private boolean isValidPayId() { 
    if (payId == null) { 
     logger.log("invalid payId."); 
     return false; 
    } 
    return true; 
    } 

    private boolean isValidClientIdDeviceId() { 
    if (clientId == null && deviceId == null) { 
     logger.log("invalid clientId and deviceId."); 
     return false; 
    } 
    return true; 
    } 

    // getters 
} 

나는 Validator 클래스에 문자열 또 다른 매개 변수 processName를 전달할 수 있습니다. 이에 따라 필드를 검증하기 위해이를 구현할 수 있습니까?

답변

1

Process 클래스의 유형이 거의 없다면 내가 제시 한 첫 번째 해결책은 수용 가능합니다.

빈 생성자를 가질 수 있으며 생성자 다음에 호출하는 프로세스에 의해 init 메서드를 가질 수 있습니다.프로세스 B에서

Validator validation = new Validator(); 
    validation.initProcessA(payload); 

: 프로세스 A의

public Validator() { 
    } 

    // for ProcessA 
    public initProcessA(GenericRecord payload) { 
    clientId = (String) DataUtils.parseRecord(payload, "clientId"); 
    deviceId = (String) DataUtils.parseRecord(payload, "deviceId"); 
    payId = (String) DataUtils.parseRecord(payload, "payId"); 
    } 

    // for ProcessB, 
    public void initProcessB(GenericRecord payload) { 
    crossId = (String) DataUtils.parseRecord(payload, "crossId"); 
    maxId = (String) DataUtils.parseRecord(payload, "maxId"); 
    minId = (String) DataUtils.parseRecord(payload, "minId"); 
    } 

:

그냥 기본 생성자 (즉를 선언 할 필요가 없습니다)를 유지

Validator validation = new Validator(); 
    validation.initProcessB(payload); 

이 첫 번째 솔루션에는 한계가 있습니다.
Process 클래스에 의존하는 유효성 검사 특수성이있는 경우 더 나은 해결 방법은 각 프로세스에 대해 고유 한 유효성 검사기 클래스로 규칙을 분해하는 것이므로 유지 관리가 더 쉽기 때문입니다.

public class ValidatorA extends Validator<ProcessA>{ 
    ... 
     public ValidatorA(GenericRecord payload){ 
      clientId = (String) DataUtils.parseRecord(payload, "clientId"); 
      deviceId = (String) DataUtils.parseRecord(payload, "deviceId"); 
      payId = (String) DataUtils.parseRecord(payload, "payId"); 
     } 

     public boolean isValid(){ 
      // validation rules specific to ProcessA 
     } 
    ... 

} 

검사기 B 프로세스 B의 경우 : 프로세스 A의

public abstract class Validator<T extends Process>{ 

    ... 
    // common and abstract methods  
    ... 
    public abstract boolean isValid(); 
} 

검사기 A : 당신은 예를 들어있을 수

최초의 솔루션으로

public class ValidatorB extends Validator<ProcessB>{ 
    ... 
     public ValidatorB(GenericRecord payload) { 
     crossId = (String) DataUtils.parseRecord(payload, "crossId"); 
     maxId = (String) DataUtils.parseRecord(payload, "maxId"); 
     minId = (String) DataUtils.parseRecord(payload, "minId"); 
     } 

     public boolean isValid(){ 
      // validation rules specific to ProcessB 
     } 

    ... 
} 
+0

, 어떻게이하는 내 그렇다면 isValid 메소드는 어떻게 생겼는가? 그렇다면 isValid는 ProcessA 또는 ProcessB의 필드를 검증해야한다는 사실을 알아야 할 필요가 있습니까? 실제 코드에서 – john

+0

이라면,'isValid()'는 두 프로세스에 공통입니다. 바람직하지 않은 경우 추상적 인 Validator 클래스와 Process 유형별로 구체적인 Validator 클래스가있는 두 번째 솔루션을 따라야한다고 생각합니다. 이 방법으로 각 구체적인 Validator 클래스에서 유효성 검사에 필요한 특이성을 정의 할 수 있습니다. – davidxxx

+0

'isValid()'는 두 프로세스에서 공통적으로 사용할 수 있습니다. 혼란 스럽지만'initProcessB'를 했으므로 isValid 메소드는 ProcessB에 대해서만 필드의 유효성을 확인해야합니다. 바로 지금 ProcessA 필드를 검증합니다. 그래서 processB를 초기화하면 isValid가 ProcessB의 필드의 유효성을 검사하여 processB 코드에서 processB의 필드를 검증하는 isValid를 호출 할 수있게합니다. 내 프로세스 모두에 대한 공통 필드 유효성 검사는 없지만 모두 다릅니다. – john

관련 문제