2010-11-16 26 views
13

Tôi quen thuộc với ý tưởng và lợi ích của một phương thức tĩnh, như mô tả trong Effective Java Joshua Bloch:Trường hợp sử dụng thực tế cho phương pháp nhà máy tĩnh?

  • phương pháp Factory có tên, vì vậy bạn có thể có nhiều hơn một phương pháp nhà máy với cùng một chữ ký, không giống như nhà thầu.
  • Phương pháp của nhà máy không phải tạo đối tượng mới; chúng có thể trả về một đối tượng được tạo trước đó. Điều này là tốt cho các đối tượng bất biến hoặc các đối tượng giá trị.
  • Phương thức của nhà máy có thể trả về đối tượng của bất kỳ loại phụ nào thuộc loại trả về của chúng, không giống như hàm tạo.

Bây giờ tôi đang cố giải thích các phương pháp nhà máy tĩnh cho người đang học các nguyên tắc Java và OO. Cô học tốt nhất từ ​​các kịch bản cụ thể thay vì trừu tượng hóa. Nếu cô ấy có thể nhìn thấy mô hình tại nơi làm việc, giải quyết một số vấn đề, cô ấy sẽ nhận được nó. Nhưng cô thấy khó đọc một danh sách trừu tượng các đặc điểm như trên để hiểu cách áp dụng mẫu.

Bạn có thể giúp tôi đưa ra một ví dụ thực tế về cách sử dụng phương pháp nhà máy tĩnh, điều này làm cho lợi ích của nó rõ ràng, nhưng vẫn đủ đơn giản để hiển thị ai đó trong lớp Java giới thiệu?

Người này không có kinh nghiệm lập trình trong PL/SQL nhưng không bao giờ có xung quanh để học các mẫu OOP.

+0

Đã kiểm tra điều này? http://stackoverflow.com/questions/929021/what-are-static-factory-methods-in-java –

Trả lời

15

Sử dụng javax.swing.BorderFactory làm ví dụ về cả ba điểm.

Lớp này được sử dụng để tạo đường viền cho các đối tượng đu. Các đối tượng biên giới này có thể dễ dàng được sử dụng lại và phương thức nhà máy này cho phép điều này. Đây là the javadoc. Nhà máy này là một ví dụ tuyệt vời về cả ba điểm:

  • Có nhiều phương pháp tĩnh với các tên khác nhau như createEmptyBorder()createEtchedBorder().
  • Các phương pháp này sẽ trả lại các đối tượng đã tạo trước đó khi có thể. Nó khá thường xuyên mà cùng một biên giới sẽ được sử dụng trong suốt một ứng dụng.
  • Border chính nó thực sự là một giao diện, vì vậy tất cả các đối tượng được tạo thông qua nhà máy này thực sự là các lớp thực hiện giao diện này.
+1

Đây là một ví dụ tuyệt vời. –

+0

@Erick Tôi thích ví dụ của bạn. Nhưng cuốn sách cũng ngụ ý ứng dụng này: Một ứng dụng linh hoạt này là một API có thể trả về các đối tượng mà không cần đặt các lớp của chúng thành công khai. Nhưng trong trường hợp ví dụ của bạn, tất cả các lớp đều được công khai. Vậy, có ví dụ nào bao gồm ứng dụng này không? – dosdebug

4

Ví dụ điển hình về điểm thứ hai của bạn là Integer.valueOf(int) (tương tự cho Boolean, Short, Long, Byte). Đối với các giá trị tham số -128 đến 127, phương thức này trả về một cá thể được lưu trong bộ nhớ cache thay vì tạo một Integer mới. Điều này làm cho (auto) boxing/unboxing nhiều hơn nữa hiệu suất cho các giá trị điển hình.

Bạn không thể làm điều đó với new Integer() vì JLS yêu cầu new tạo phiên bản mới mỗi khi được gọi.

3

Sẽ không Calendar.getInstance() là một hình ảnh tốt? Nó tạo tùy thuộc vào miền địa phương một BuddhistCalendar, JapaneseImperialCalendar hoặc theo mặc định là một GregorianCalendar.

+0

-1 Đây không phải là câu trả lời, đó là một câu hỏi. –

0

Đây là một trong những điều tôi phải làm khi trở lại. Tại một cuộc phỏng vấn xin việc, tôi được yêu cầu lập trình một cỗ bài, nơi họ có thể xáo trộn. Vấn đề thực sự đơn giản.Tôi đã tạo:

Card: 
    suit 
    rank 

Deck: 
    card[] 

Tôi nghĩ yếu tố phân biệt là chỉ có 52 thẻ ở mọi thời điểm. Vì vậy, tôi đã tạo ra hàm tạo cho Card() riêng và thay vào đó tạo ra giá trị nhà máy tĩnhOf (phù hợp, xếp hạng) Điều này cho phép tôi lưu trữ 52 thẻ và làm cho không thay đổi. Nó dạy nhiều bài học cơ bản quan trọng trong những cuốn sách đó.

  1. bất biến
  2. điều khiển việc tạo đối tượng
  3. phương pháp tĩnh
  4. thể subclassing và trả về một thẻ từ một nguồn khác. (Tôi đã không làm điều này)

Điều này tương tự như Boolean và Byte, ngoại trừ tôi đã sử dụng một ví dụ về bài tập về nhà phổ biến để cho biết lý do quan trọng để kiểm soát các trường hợp. Tôi cũng đã tạo ra một hàm trợ giúp cho tầng được gọi là newDeck() vì tôi muốn hiển thị một cá thể trong đó hàm tạo có thể không cần phải riêng tư nhưng nó vẫn sẽ rất tốt nếu có một nhà máy trợ giúp tĩnh.

Tôi hy vọng điều này sẽ hữu ích!

+0

Với ví dụ cụ thể này tôi thậm chí có thể theo đuổi một enum, vì nó được biết đến tại thời gian biên dịch mỗi trường hợp duy nhất của lớp học của bạn mà bao giờ có thể được tạo ra. –

+0

Tôi thực sự đã làm một enum! Tôi đã làm hai, ba, bốn ... jack, nữ hoàng, vua, và ace. Tôi cũng tạo ra trái tim, câu lạc bộ, spades và kim cương. Điều này làm việc hoàn hảo bởi vì tất cả mọi thứ đã được kiểm tra tĩnh tại thời gian biên dịch và các tham số của tôi cho valueOf (Rank rank, Suit suit). Rất đơn giản nhưng vẫn dạy rất nhiều về lập trình OO. –

0

Trường hợp đơn giản. Giả sử bạn có một lớp hoạt động một số loại máy in, nhưng nó không quan tâm nếu nó là epson, canon hay cái gì khác. Vì vậy, bạn chỉ cần tạo một Giao diện Printer, tạo một số triển khai của nó và tạo một lớp chỉ có một phương thức: createPrinter.

Vì vậy, mã sẽ được đơn giản: Mã

public interface Printer { 
     print(); 
    } 

    class CanonPrinter implements Printer { 
     print() { 
    // ... 
     } 
    } 


    public PrinterFactory { 

    Printer createPrinter() { 
    if (...) { 
     return new CanonPrinter(); 
    } else { 
     return new EpsonPrinter(); 
    } 
} 
} 

khách hàng:

Printer printer = PrinterFactory.createPrinter(); 
printer.print(); 

Ở đây bạn trừu tượng bạn clinet mã từ bất kỳ chi tiết về những gì máy in bạn có thể hoạt động với hoặc cách họ quản lý in ấn . Đó là PrinterFactory, người quan tâm đến máy in nào để chọn nếu máy in bị trục trặc.

4

Ví dụ yêu thích hiện tại của tôi về mẫu này là Guava 's ImmutableList. Các trường hợp của nó chỉ có thể được tạo ra bởi các nhà máy tĩnh hoặc một nhà xây dựng. Dưới đây là một số cách mà đây là thuận lợi:

  • Kể từ ImmutableList không tiếp xúc với bất kỳ public hoặc protected nhà xây dựng, nó có thể được subclassed trong gói trong khi không cho phép người dùng phân lớp nó (và có khả năng phá vỡ đảm bảo tính bất biến của nó).
  • Cho rằng, các phương pháp nhà máy của nó đều có khả năng trả về các lớp con chuyên biệt của nó mà không lộ ra loại của chúng.
  • Phương thức nhà máy ImmutableList.of() trả về phiên bản đơn lẻ là . Điều này chứng tỏ làm thế nào một phương pháp nhà máy tĩnh không cần phải tạo một thể hiện mới nếu nó không phải.
  • Phương thức ImmutableList.of(E) trả về phiên bản SingletonImmutableList được tối ưu hóa vì nó sẽ chỉ giữ chính xác 1 phần tử.
  • Hầu hết các phương pháp nhà máy khác của nó đều trả lại RegularImmutableList.
  • Phương thức nhà máy tĩnh copyOf(Collection) cũng không phải lúc nào cũng cần phải tạo một phiên bản mới ... nếu Collection nó được cung cấp là chính nó là ImmutableList, nó chỉ có thể trả về điều đó!
+0

OK Tôi sẽ cắn. Chính xác những gì một người sẽ làm với một danh sách bất biến không có sản phẩm nào? –

+2

@Chris: Điều tương tự cũng có, ví dụ, 'Collections.emptyList() '(cũng là một singleton không thay đổi). Khi một phương thức trả về một 'List' không có bất kỳ dữ liệu nào để trả về, nó luôn luôn trả về một' Danh sách' trống rỗng hơn là 'null'. Vì một bộ sưu tập rỗng, không thay đổi không bao giờ có thể chứa bất kỳ dữ liệu nào, một cá thể đơn lẻ có thể được sử dụng ở mọi nơi cần thiết. Thêm vào đó, trường hợp đó có thể nhẹ nhất có thể vì nó thậm chí không cần bất kỳ cấu trúc dữ liệu nội bộ nào để giữ bất cứ thứ gì. – ColinD

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