2014-06-24 7 views
2

RecordFilter 인터페이스를 사용하여 일부 레코드를 필터링하려고합니다. 내 응용 프로그램에서 나는j2me - 두 개 이상의 기준으로 결과 필터링

여기

enter image description here

내가 '무엇 (그/그녀가 너무 둘 또는 둘을 입력 할 수 있습니다) 사용자가 ID 또는 이름을 입력 할 수있는, 이것과 같은 인터페이스의 몇 가지를 가지고 지금까지 완료 :

고객 필터.

참고 :이 사용자가 ID를 입력하지 않은 경우, 나는이 기본 값으로 0을 전달 여기

, 그건 내가 customerID!=0

public class CustomerFilter implements RecordFilter { 

    private String mName_Filter; 
    private int mID_Filter; 

    public CustomerFilter(String name_Filter, int id_Filter) { 
     this.mName_Filter = name_Filter.toLowerCase(); 
     this.mID_Filter = id_Filter; 
    } 

    public boolean matches(byte[] candidate) { 
     try { 
      ByteArrayInputStream bis = new ByteArrayInputStream(candidate); 
      DataInputStream dis = new DataInputStream(bis); 
      int customerID = dis.readInt(); 
      String customerName = dis.readUTF().toLowerCase(); 
      if ((customerName != null && customerName.indexOf(mName_Filter) != -1) && (customerID != 0 && customerID == mID_Filter))     
       return true; 
      if (customerName != null && customerName.indexOf(mName_Filter) != -1 && customerID == 0) 
       return true; 
      if (customerName == null && (customerID != 0 && customerID == mID_Filter)) 
       return true; 
      if (customerName == null && customerID == 0) 
       return true; 

     } catch (IOException ex) { 
      //What's the point in catching a exception here??? 
     } 
     return false; 
    } 
} 

검색 방법을 평가하는 이유 메서드는 "RMSCustomer"라고하는 클래스에 있으며 RMS 액세스와 관련된 모든 것을 처리합니다. 검색 메소드는 두 개의 매개 변수 (id 및 name)를 수신하고이를 사용하여 필터를 인스턴스화합니다.

1) 나는 가능한 값을 평가하는 코드를 향상시킬 수있는 방법 : 필터에서

:

public Customer[] search(int id, String name) throws RecordStoreException, IOException { 
     RecordStore rs = null; 
     RecordEnumeration recEnum = null; 
     Customer[] customerList = null; 
     try { 
      rs = RecordStore.openRecordStore(mRecordStoreName, true);   
      if (rs.getNumRecords() > 0) { 
       CustomerFilter filter = new CustomerFilter(name, id);    
       try { 
        recEnum = rs.enumerateRecords(filter, null, false); 
        if (recEnum.numRecords() > 0) {     
         customerList = new Customer[recEnum.numRecords()]; 
         int counter = 0; 
         while (recEnum.hasNextElement()) { 
          Customer cust; 
          int idRecord = recEnum.nextRecordId(); 
          byte[] filterRecord = rs.getRecord(idRecord);      
          cust = parseRecord(filterRecord); 
          cust.idRecord = idRecord; 
          customerList[counter] = cust; 
          counter++; 
         } 
        } 
        else{ 
         customerList = new Customer[0]; 
         //How to send a message to the midlet from here 
         //saying something like "No Record Exists.Please select another filter" 
        }     
       } finally { 
        recEnum.destroy(); 
       } 
      } 
      else{ 
       //How to send a message to the midlet from here 
       //saying something like "No Record Exists.Please Add record" 
      } 
     } finally { 
      rs.closeRecordStore(); 
     } 
     return customerList; 
    } 

은 비록, 작품 위에 표시된 코드는 여전히 몇 가지 질문/문제가 필터 (이름, id)? 더 많은 필터가 있다면 어떨까요 ?? 가능한 모든 조합을 테스트해야합니까 ??

2) 사용자가 ID도 이름도 입력하지 않으면 모든 레코드를 표시해야합니까? 아니면 "이름 또는 ID를 입력하십시오"라는 메시지가 표시되어야합니까? 이 경우 당신은 무엇을 할 것입니까?

3) 왜 아무것도 할 수 없을 때 필터에 try-catch를 넣어야합니까? 거기에서 어떤 경고도 표시 할 수 없나요? 검색 방법에서

:

1) 어떻게 그 방법에서 사용자에게 적절한 메시지를 표시 할 수 있습니까? 내가 너무 많은 질문을하면 "아니오 기록"(같은 필터의 완전한 예제가 있다는 그것은 단지, 내 코드에서 "ELSE"부품

죄송를 참조하십시오. 사전에

감사를

답변

2

내가 (이름, ID)?를 필터의 가능한 값을 평가하는 코드를 향상시킬 수있는 방법

ID가 기록 및 검색 할 수있는 가장 빠른 하나의 첫 번째 필드입니다. 이드가 일치하면, 그것은하지 않습니다. 고객 이름이 무엇인지 확인하십시오. 일반적으로 ID가 일치하거나 고객 이름이 일치하는 레코드를 찾고 있으므로 ID가 일치하면 true를 반환 할 수 있습니다.이것은 CustomerFilter 클래스에 대한 나의 제안이다 :

public class CustomerFilter implements RecordFilter { 

    private String mName_Filter; 

    //Use Integer instead of int. 
    //This way we can use null instead of zero if the user didn't type an ID. 
    //This allows us to store IDs with values like 0, -1, etc. 
    //It is a bit less memory efficient, 
    //but you are not creating hundreds of filters, are you? (If you are, don't). 
    private Integer mID_Filter; 

    public CustomerFilter(String name_Filter, Integer id_Filter) { 
     this.mName_Filter = normalizeString(mName_Filter); 
     this.mID_Filter = id_Filter; 
    } 

    //You should move this function to an StringUtils class and make it public. 
    //Other filters might need it in the future. 
    private static String normalizeString(final String s){ 
     if(s != null){  
      //Warning: you might want to replace accentuated chars as well. 
      return s.toLowerCase(); 
     } 
     return null; 
    } 

    public boolean matches(byte[] candidate) { 
     ByteArrayInputStream bis = new ByteArrayInputStream(candidate); 
     DataInputStream dis = new DataInputStream(bis); 

     try {    
      if(mID_Filter != null){ 
       //If the ID is unique, and the search is ID OR other fields, this is fine 
       int customerID = dis.readInt(); 

       if(mID_Filter.intValue == customerID){ 
        return true; 
       } else { 
        return false; 
       } 
      } 

      if(mName_Filter != null){ 
       String customerName = normalizeString(dis.readUTF()); 
       if(customerName != null && customerName.indexOf(mName_Filter) != -1){ 
        return true; 
       } 
      } 

      if(mID_Filter == null && mName_Filter == null){ 
       return true; // No filtering, every record matches. 
      } 
     } catch (IOException ex) { 
      //Never swallow exceptions. 
      //Even if you are using an underlying ByteArrayInputStream, an exception 
      //can still be thrown when reading from DataInputStream if you try to read 
      //fields that do not exists. 

      //But even if no exceptions were ever thrown, never swallow exceptions :) 
      System.err.println(ex); 

      //Optional: throw ex; 
     } finally { 
      //Always close streams. 
      if(bis != null){ 
       try { 
        bis.close(); 
       } catch(IOException ioe){ 
        System.err.println(ioe); 
       } 
      } 

      if(dis != null){ 
       try { 
        dis.close(); 
       } catch(IOException ioe){ 
        System.err.println(ioe); 
       } 
      } 
     } 

     return false; 
    } 
} 




내가 더 필터를한다면 어떨까요? 가능한 모든 조합을 테스트해야합니까 ??

프로젝트에 따라 다릅니다. 일반적으로 ID는 고유하며 두 ID가 같은 레코드가 없습니다. 이 경우 사용자가 ID를 입력하거나 다른 필드를 채우는 것을 사용자가 이해할 수 있도록 화면을 명시 적으로 디자인해야합니다. 조건은 다음과 같습니다.

사용자가 아무 것도 입력하지 않으면 모든 레코드가 반환됩니다.

그러나 이것은 다시 UX 문제이며 사용자의 요구 사항에 맞는지는 알 수 없습니다.

프로그래밍 관점에서 볼 때, 추가하는 필드가 많을수록 필터가 더 복잡해집니다. 이를 방지하려면 Decorator, Composite 및 심지어 Chain of responsibility과 같은 패턴을 사용할 수 있습니다. 당신은 아마도 성능을 위해 좋은 디자인을 교환해야 할 것입니다. 사용자가 ID 나 이름도 입력하지 않는 경우




, 내가 모든 레코드를 표시해야합니다 아니면 메시지를 표시해야합니다 "이름 또는 ID를 입력하십시오"? ? 이 경우 당신은 무엇을 할 것입니까?

에 달려 있습니다. 모든 기록을 볼 수있는 다른 방법이 있습니까? 그렇다면 메시지를 표시하십시오.




왜 내가 거기에 아무것도 할 수 없을 때 필터에 시도 - 캐치를 넣어해야합니까? 거기에서 어떤 경고도 표시 할 수 없나요?

하지 않아야합니다. 이 클래스는 사용자와 상호 작용하지 않고 필터링 만 담당합니다. catch 절에서 오류를 기록한 다음 예외를 다시 throw 할 수 있습니다. 그것은 RMSCustomer.search까지 예외를 전파 할 것이고, 그래서 어떤 클라이언트 코드가 그 함수를 호출하고 있더라도 그 메소드에 의해 던져진 다른 것들을 처리하는 것과 같은 방식으로 예외를 처리 할 것이다. 그러나 스트림을 닫으려면 finally 절을 유지하십시오.




어떻게 그 방법에서 사용자에게 적절한 메시지를 표시 할 수 있습니까? RMSCustomer 클래스 "아니오 기록"(내 코드에서 "ELSE"부분 참조)

당신은 (보여주는 대화 상자 같은) GUI에 관련된 아무것도하지 말아야 같은 뭔가.Model-View-Controller 패턴을 사용하지 않더라도 클래스를 단일 책임 (레코드 관리)에 집중시키는 것이 좋습니다. 이를 Single responsibility principle이라고합니다. GUI와 분리 된 클래스를 유지하면 GUI없이 테스트하고 재사용 할 수 있습니다. 결과가 0 일 때 화면에 의해 레코드가없는 경우를 처리해야합니다. lenght == 0의 배열이 여기에 좋으며 화면에 "결과 없음"메시지가 표시됩니다. 다른 종류의 오류가 발생하면 Exception 클래스를 확장하고 사용자 정의 예외 (예 :)를 RMSCustomer.search 메소드에서 가져올 수 있습니다. 그런 다음 화면 클래스는 여러 예외를 사용자의 언어로 오류 메시지에 매핑합니다.

+0

고맙습니다. 스미스 미스터 스미스 – Axel

관련 문제