2013-04-23 61 views
11

Tôi có hai phương pháp tương tự. Một trong số họ in một cái gì đó và một trong số họ tiết kiệm somethings. Như bạn có thể thấy có rất nhiều mã trùng lặp. Làm thế nào tôi nên refactor nó và loại bỏ trùng lặp này?Cách xóa trùng lặp khỏi mã của tôi

public static void printSomething(List<String> list) { 
    for (String item : list) { 
     if (item.contains("aaa")) { 
      System.out.println("aaa" + item); 
     } 
     if (item.contains("bbb")) { 
      System.out.println("bbb" + item); 
     } else { 
      System.out.println(item); 
     } 
    } 
} 

public static Map<String, String> getSomething(List<String> list) { 
    Map<String, String> map = new HashMap<String, String>(); 
    for (String item : list) { 
     if (item.contains("aaa")) { 
      map.put("aaa", item); 
     } 
     if (item.contains("bbb")) { 
      map.put("bbb", item); 
     } else { 
      //do nothing 
     } 
    } 
    return map; 
} 

UPDATE:

Mã đã được cập nhật để giải quyết vấn đề khi phương pháp không chính xác tương tự

+0

Nó phụ thuộc ... tại sao bạn có những 2 phương pháp ... bạn có thể chia sẻ các phương thức gọi – Frank

+0

Bạn có thể sử dụng giá trị trả về của 'getSomething()' để thực hiện các bản in trong 'printSomething()'; Tôi sẽ đi theo cách này để tránh các phương thức không trả lại (không phải là setters ofc). – adrianp

+0

@HighPerformanceMark xin lỗi vì nhầm lẫn. Ý tôi là sao chép – hudi

Trả lời

3

Một hành động giao diện chung mà có một phương pháp hành động (T t) có thể làm giảm mã.

public interface Action<E> { 
     void action(E e); 
} 

Ví dụ:

public static void forEach(List<String> list, Action <String> action) { 
    for(String s : list){ 
      action.action(s); 

} 

Bây giờ bạn chỉ cần 2 triển khai khác nhau của hành động.

Bạn có thể sử dụng các loại kết hợp nếu bạn không muốn tạo lớp học.

Nếu bạn biết C# điều này tương tự như lambdas.

chỉnh sửa:

Sử dụng loại annonymous:

public static Map<String, String> getSomething(List<String> list) { 
    final Map<String, String> map = new HashMap<String, String>(); 
    forEach(list, new Action<String>() { 
     @Override 
     public void action(String e) { 
      if (e.contains("aaa")) { 
       map.put("aaa", e); 
      } 
      if (e.contains("bbb")) { 
       map.put("bbb", e); 
      } else { 
       // do nothing 
      } 
     } 
    }); 
    return map; 
} 

Tạo lớp:

public static Map<String, String> getSomething2(List<String> list) { 
    final Map<String, String> map = new HashMap<String, String>(); 
    forEach(list, new ListToMapAction(map)); 
    return map; 
} 


public class ListToMapAction implements Action<String> { 

    Map<String, String> map; 

    public ListToMapAction(Map<String, String> map) { 
     this.map = map; 
    } 

    @Override 
    public void action(String e) { 
     if (e.contains("aaa")) { 
      map.put("aaa", e); 
     } 
     if (e.contains("bbb")) { 
      map.put("bbb", e); 
     } else { 
      // do nothing 
     } 
    } 

} 
+0

xin lỗi nhưng tôi không hiểu ví dụ của bạn. Phương thức của bạn không trả lại gì nên tôi nên lấy bản đồ của mình như thế nào? – hudi

+0

chỉnh sửa với đầy đủ thực hiện –

+0

khi bạn chỉ cần in một cái gì đó? Tôi nghĩ rằng sẽ vẫn còn một số trùng lặp trong phương thức hành động – hudi

2

Trong một ngôn ngữ lập trình với các chức năng hạng nhất, bạn muốn vượt qua xung quanh một chức năng như một tham số chỉ ra những gì bạn muốn làm bên trong vòng lặp (cho một ví dụ xem cập nhật, bên dưới). Java sẽ có lambdas trong phiên bản 8, nhưng chúng không hoàn toàn phù hợp với công việc.

Trong trạng thái hiện tại của Java, bạn sẽ phải giải quyết với thứ gì đó xấu xí hơn - ví dụ, chuyển một tham số bổ sung cho phương thức; hoặc bạn có thể vượt qua xung quanh lớp bên trong vô danh mà thực hiện một giao diện, nhưng IMHO mà thậm chí còn xấu hơn những gì tôi sắp đề nghị:

static void printSomething(List<String> list, boolean print) 

Nếu printtrue sau đó in bên trong vòng lặp, nếu không thêm vào Map. Tất nhiên, bạn sẽ phải thêm một vài số if trong vòng lặp để kiểm tra điều kiện này và ngay từ đầu, thêm một số if để xác định xem Map có được khởi chạy hay không. Dù bằng cách nào, phương thức trả về một số Map, nhưng Map có thể là null cho trường hợp in. Đây là những gì tôi muốn nói:

static Map<String, String> processSomething(List<String> list, boolean print) { 

    Map<String, String> map = null; 
    if (!print) 
     map = new HashMap<String, String>(); 

    for (String item : list) { 
     if (item.contains("aaa")) { 
      if (print) 
       System.out.println("aaa" + item); 
      else 
       map.put("aaa", item); 
     } 
     if (item.contains("bbb")) { 
      if (print) 
       System.out.println("bbb" + item); 
      else 
       map.put("bbb", item); 
     } else if (print) { 
      System.out.println(item); 
     } 
    } 

    return map; 

} 

CẬP NHẬT

Ví dụ, trong Python - cho phép các chức năng thông qua các tham số, đây là cách bạn muốn giải quyết vấn đề trong một thời trang thanh lịch:

def processSomething(lst, func): 
    result = None 
    for item in lst: 
     if 'aaa' in item: 
      result = func(item, 'aaa', result) 
     elif 'bbb' in item: 
      result = func(item, 'bbb', result) 
     else: 
      result = func(item, '', result) 
    return result 

def printer(item, key, result): 
    print key + item 

def mapper(item, key, result): 
    if not result: 
     result = {} 
    if key: 
     result[key] = item 
    return result 

Xem cách hoạt động:

processSomething(['aaa', 'bbb', 'ccc'], printer) 
=> aaaaaa 
    bbbbbb 
    ccc 

processSomething(['aaa', 'bbb', 'ccc'], mapper) 
=> {'aaa': 'aaa', 'bbb': 'bbb'} 
+3

đây là ví dụ rất xấu. Tên đầu tiên của phương pháp này in hoặc nhận được ?? Thứ hai bạn vẫn có khoảng trống để bạn không trả lại gì cả – hudi

+0

Tên có thể là một cái gì đó chung chung. Và phương pháp phải trả về Bản đồ luôn, ngay cả khi nó là trống –

+0

Lời khuyên tốt. Và bạn luôn có thể vượt qua trong việc triển khai giao diện - mẫu đại biểu. –

7

Assu ming thứ tự trong đó println của "aaa""bbb" xuất hiện không quan trọng, bạn có thể thay thế việc thực hiện printSomething với

public static void printSomething(List<String> list) { 
    Map<String, String> map = getSomething(list); 
    for(Map.Entry<String, String> entry : map) { 
    System.out.println(entry.getKey() + entry.getValue()); 
    } 
} 
+0

+1. Đây là giả định thứ tự của bản in không quan trọng mặc dù. – Keppil

+0

Phải - Tôi muốn viết điều đó, cảm ơn vì đã chỉ ra. – tehlexx

+0

hm thx điều này sẽ hoạt động nếu phương thức sẽ giống nhau nhưng nếu in sẽ chứa: ... else {System.out.println ("bbb" + item); } và nhận được ... else {// doNothing} – hudi

Các vấn đề liên quan