2013-04-26 43 views
6

Tôi có một lớp util thực hiện một số công việc. Rõ ràng, nó được đóng để mở rộng và tất cả các phương thức đều tĩnh. Vì lợi ích của sự đơn giản, lớp trông như thế này:Mẫu phương thức mẫu cho các lớp tĩnh

public final class Util { 
    private Util() { } 

    public static void doWork() { 
     // some work 
     int variable = help(); 
     // some work uses variable 
    } 

    private static int help() { 
     // some helper functionality 
    } 
} 

Lớp có phương pháp doWork mà thực hiện rất nhiều tính toán. Nhân tiện, phương thức gọi phương thức trợ giúp help để nhận được một số kết quả và phần còn lại của mã sử dụng kết quả được trả về theo phương thức help.

Bây giờ, trong mã khách hàng Tôi muốn sử dụng lại chức năng của phương pháp doWork, nhưng thay vì gọi help Tôi muốn gọi help2 phương pháp. Giải pháp đơn giản nhất chỉ cần tạo phương thức doWork2 thay thế help thành help2.

Phương pháp tiếp cận rất xấu, bởi vì mọi thay đổi trong số doWork cũng phải được sao chép trong doWork2. Điều này rất giống với mẫu Template Method, nhưng do thực tế là chúng tôi không có phần mở rộng ở đây, chúng tôi không thể áp dụng nó.

giải pháp tốt nhất mà tôi đã đưa ra để thêm tham số để phương pháp này, nhưng giữ gìn tất cả các người dùng hiện tại của doWork:

public static void doWork() { 
    doWorkWithParameter(true); 
} 

public static void doWorkWithParameter(boolean helpOrHelp2) { 
    // some work 
    int variable = helpOrHelp2 ? help() : help2(); 
    // some work uses variable 
} 

gì được các giải pháp thiết kế tốt hơn có thể được áp dụng để giải quyết vấn đề này? Có cách nào để đạt được sự linh hoạt như Template Pattern, nhưng trong ứng dụng để sử dụng các lớp học.

Xin cảm ơn trước.

+0

Có bất cứ lý do bạn không sử dụng phương pháp quá tải trong giải pháp của bạn? 'public static void doWork() {...}' 'public static void doWork (boolean param) {...}' – Crazenezz

+0

Hoặc tốt hơn vẫn 'public static void doWork (int variable)'. Mặc dù tôi nghi ngờ câu trả lời thực tế là sự nhầm lẫn là do các thống kê và rằng các đối tượng sẽ cung cấp một câu trả lời rõ ràng hơn - khó nói với các ví dụ trừu tượng mặc dù. –

+0

Điều bạn đang tìm kiếm là Chiến lược mẫu. Kiểm tra câu trả lời của Arnaldo. –

Trả lời

5

Đề nghị của tôi được lấy cảm hứng trong Command Pattern, nơi util lớp là một Invoker và mỗi DoWork giúp đỡ cặp được đóng gói bằng cách sử dụng giao diện người lao động.

Các Worker inteface thể có một số như

public interface Worker { 
    public void doWork(); 
    public int help(); 
} 

Các util lớp

public final class Util { 
    private Util() { } 

    public static void toWork(Worker worker){ 
     worker.doWork(); 
    } 

} 

Các Worker bê tông (triển khai giúp đỡ và DoWork)

public class ConcreteWorker implements Worker{ 

    @Override 
    public void doWork() { 
     // TODO Auto-generated method stub 
      int variable = help(); 

    } 

    @Override 
    public int help() { 
     // TODO Auto-generated method stub 
     return 0; 
    } 

} 

Một Worker

public class ConcreteWorker2 implements Worker{ 

    @Override 
    public void doWork() { 
     // TODO Auto-generated method stub 
      int variable = help(); 

    } 

    @Override 
    public int help() { 
     // TODO Auto-generated method stub 
     return 1; 
    } 

} 

Và Thực hiện

Util.toWork(new ConcreteWorker()); 
Util.toWork(new ConcreteWorker2()); 
+0

Thay vì giao diện Công nhân, bạn nên làm cho nó trở thành lớp trừu tượng với phương thức doWork(). Điều này thực sự giống như những gì tôi đề xuất, nhưng chỉ với nhiều mã hơn. Bạn có bốn lớp thay vì một. Tôi giả sử enums là tốt hơn thay thế các phương pháp tĩnh. – Mikhail

+1

Tuyệt vời! Nó trông giống như mẫu chiến lược 'Collections.sort (lst, Comparator)'. Làm thế nào tôi có thể bỏ lỡ điều đó? – mishadoff

1

Bạn có thể tạo ra 2 đối tượng tĩnh Help1 & Help2 thực hiện Help giao diện Mà có một phương pháp giúp đỡ() và thay đổi phương thức doWorkWithParameter của bạn như thế này:

public static void doWorkWithParameter(Help h) { 
    int variable = h.help(); 
} 

Nó liên quan chặt chẽ với giải pháp hiện tại của bạn. Nhưng tôi nghĩ đó là một chút "Hướng đối tượng".

1

Không phải như vậy thời gian dài trước đây, tôi đã thực hiện điều này:

public static enum Helper{ 
    OLD(){ 
     public int help(){ 
      return 0; 
     } 
    }, 

    NEW(){ 
     public int help(){ 
      return 1; 
     } 
    }; 

    public abstract int help(); 

    public void doWork() { 
     int variable = help(); 
    } 
} 

public static Helper HELPER = Helper.NEW; 

sau đó chúng ta có thể gọi:

Constants.HELPER.doWork() 

Bằng cách chuyển NGUỒN HỖ TRỢ giá trị không đổi tôi có thể thay đổi hành vi. hoặc bạn có thể làm:

Helper.OLD.doWork(); 
Helper.NEW.doWork(); 
+0

Cảm ơn, mẹo hay. – mishadoff

+0

Đây là từ sách Java hiệu quả - "Mục 34: Mô phỏng các enums mở rộng với giao diện" – Mikhail

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