Ví dụ về các mẫu thiết kế GoF trong các thư viện cốt lõi của Java


672

Tôi đang học các mẫu thiết kế Java của GoF và tôi muốn xem một số ví dụ thực tế về chúng. Một số ví dụ hay về các Mẫu thiết kế này trong các thư viện cốt lõi của Java là gì?

Câu trả lời:


3229

Bạn có thể tìm thấy một cái nhìn tổng quan về rất nhiều mẫu thiết kế trong Wikipedia . Nó cũng đề cập đến các mẫu được đề cập bởi GoF. Tôi sẽ tổng hợp chúng ở đây và cố gắng chỉ định càng nhiều triển khai mẫu càng tốt, được tìm thấy trong cả API Java SE và Java EE.


Mô hình sáng tạo

Nhà máy trừu tượng (có thể nhận biết bằng các phương thức sáng tạo trả về chính nhà máy mà lần lượt có thể được sử dụng để tạo một loại giao diện / trừu tượng khác)

Trình tạo (có thể nhận biết bằng các phương thức tạo trả về chính thể hiện)

Phương thức xuất xưởng (có thể nhận biết bằng các phương thức sáng tạo trả về việc triển khai loại trừu tượng / giao diện)

Nguyên mẫu (có thể nhận biết bằng các phương thức sáng tạo trả về một thể hiện khác của chính nó có cùng thuộc tính)

Singleton (có thể nhận ra bằng các phương thức sáng tạo trả về cùng một thể hiện (thường là của chính nó) mọi lúc)


Mô hình kết cấu

Bộ điều hợp (có thể nhận biết bằng các phương thức sáng tạo lấy một thể hiện của loại giao diện / trừu tượng khác nhau và trả về một triển khai của loại / giao diện trừu tượng / riêng khác để trang trí / ghi đè lên thể hiện đã cho)

Cầu nối (có thể nhận biết được bằng các phương thức sáng tạo lấy một thể hiện của loại giao diện / trừu tượng khác nhau và trả về một triển khai loại trừu tượng / giao diện riêng mà đại biểu / sử dụng thể hiện đã cho)

  • Không có gì đến với tâm trí chưa. Một ví dụ giả tưởng sẽ new LinkedHashMap(LinkedHashSet<K>, List<V>)trả về một bản đồ được liên kết không thể thay đổi, không sao chép các mục, nhưng sử dụng chúng. Các phương pháp java.util.Collections#newSetFromMap()singletonXXX()tuy nhiên đến gần.

Kết hợp (có thể nhận biết bằng các phương thức hành vi lấy một thể hiện của cùng loại trừu tượng / giao diện vào cấu trúc cây)

Trình trang trí (có thể nhận biết bằng các phương thức sáng tạo lấy một thể hiện của cùng loại trừu tượng / giao diện có thêm hành vi bổ sung)

Mặt tiền (có thể nhận biết bằng các phương thức hành vi sử dụng nội bộ các loại giao diện / trừu tượng độc lập khác nhau)

Fly weight (có thể nhận ra bằng các phương thức sáng tạo trả về một thể hiện được lưu trong bộ nhớ cache, một chút ý tưởng "multiton")

Proxy (có thể nhận biết được bằng các phương thức tạo trả về việc triển khai loại trừu tượng / giao diện đã cho, lần lượt đại biểu / sử dụng một triển khai khác của loại trừu tượng / giao diện đã cho)


Mẫu hành vi

Chuỗi trách nhiệm (có thể nhận ra bằng các phương thức hành vi (gián tiếp) gọi cùng một phương thức trong một triển khai khác của cùng loại trừu tượng / giao diện trong hàng đợi)

Lệnh (có thể nhận biết bằng các phương thức hành vi trong một loại trừu tượng / giao diện gọi ra một phương thức trong việc thực hiện một loại trừu tượng / giao diện khác đã được gói gọn trong quá trình thực thi lệnh trong quá trình tạo)

Trình thông dịch (có thể nhận biết bằng các phương thức hành vi trả về một thể hiện / loại khác nhau về cấu trúc của loại / thể hiện đã cho; lưu ý rằng phân tích cú pháp / định dạng không phải là một phần của mẫu, xác định mẫu và cách áp dụng nó)

Trình lặp (có thể nhận ra bằng các phương thức hành vi trả về tuần tự các thể hiện của một loại khác từ hàng đợi)

Người hòa giải (có thể nhận biết bằng các phương thức hành vi lấy một thể hiện của loại giao diện / trừu tượng khác nhau (thường sử dụng mẫu lệnh) mà đại biểu / sử dụng thể hiện đã cho)

Memento (có thể nhận ra bằng các phương thức hành vi làm thay đổi trạng thái của toàn bộ trường hợp)

Người quan sát (hoặc Xuất bản / Đăng ký) (có thể nhận biết bằng các phương thức hành vi gọi một phương thức trên một thể hiện của loại giao diện / trừu tượng khác , tùy thuộc vào trạng thái của chính họ)

Trạng thái (có thể nhận biết bằng các phương thức hành vi thay đổi hành vi của nó tùy thuộc vào trạng thái có thể được kiểm soát bên ngoài)

Chiến lược (có thể nhận biết bằng các phương thức hành vi trong một loại trừu tượng / giao diện gọi ra một phương thức trong việc thực hiện một loại giao diện / trừu tượng khác đã được truyền vào dưới dạng đối số phương thức trong triển khai chiến lược)

Phương thức mẫu (có thể nhận biết bằng các phương thức hành vi đã có hành vi "mặc định" được xác định bởi một loại trừu tượng)

Visitor (recognizeable bởi hai khác nhau các loại giao diện trừu tượng / trong đó có phương pháp xác định mà có mỗi việc khác loại giao diện trừu tượng /; một trong những thực sự gọi phương thức của người kia và thực thi chiến lược khác mong muốn trên nó)


23
ấn tượng .. :) +1. javax.lang.model.elementđịnh nghĩa khách truy cập;) Tôi không chắc chắn liệu doXXXdoFiltercó phải là "chiến lược" hay không.
Bozho

16
Các trình xây dựng được đề cập, ví dụ StrinbgBuilder không phải là một ví dụ cho Builder-Pattern. Tuy nhiên, đây là một lỗi rất phổ biến khi coi họ là người xây dựng (vì vậy bạn không thực sự đổ lỗi ^ _ ^)
Angel O'Sphere

77
@BalusC, tôi có một câu hỏi muốn hỏi bạn. Bạn đã đọc mã nguồn WHOLE của Java và JSF chưa?
Tapas Bose

20
@Tapas: Tôi không đọc tất cả mọi thứ, chỉ những phần tôi cần hoặc chỉ tò mò về cách "họ" đã làm điều đó.
BalusC

7
Hầu hết các ví dụ trong "Phương thức nhà máy" là các ví dụ về "nhà máy tĩnh" không phải là mẫu GoF. Không chính xác.
người mang nhẫn

107
  1. Mẫu quan sát trong toàn bộ swing ( Observable, Observer)
  2. MVC cũng trong swing
  3. Adapter Pattern: InputStreamReader và OutputStreamWriter LƯU Ý: ContainerAdapter, ComponentAdapter, FocusAdapter, KeyAdapter, MouseAdapterkhông adapter; chúng thực sự là các đối tượng Null. Lựa chọn đặt tên kém của Sun.
  4. Mẫu trang trí ( BufferedInputStreamcó thể trang trí các luồng khác như FilterInputStream)
  5. Mẫu Trừu tượng cho Bộ công cụ AWT và các lớp giao diện có thể cắm được
  6. java.lang.Runtime#getRuntime() là người độc thân
  7. ButtonGroup cho mẫu Người hòa giải
  8. Action, AbstractActioncó thể được sử dụng cho các biểu diễn trực quan khác nhau để thực thi cùng một mã -> Mẫu lệnh
  9. Các chuỗi thực tập hoặc CellRender trong JTable cho mẫu Flykg (Cũng nghĩ về các nhóm khác nhau - Nhóm luồng, nhóm kết nối, nhóm đối tượng EJB - Flykg thực sự là về quản lý tài nguyên được chia sẻ)
  10. Mô hình sự kiện Java 1.0 là một ví dụ về Chuỗi trách nhiệm, cũng như Bộ lọc Servlet.
  11. Mẫu lặp trong Bộ sưu tập Khung
  12. Các thùng được lồng trong AWT / Swing sử dụng mẫu Tổng hợp
  13. Trình quản lý bố cục trong AWT / Swing là một ví dụ về Chiến lược

và nhiều hơn nữa tôi đoán


1
Cảm ơn các mẹo trên MouseAd CHƯƠNG. Tôi đã tìm thấy ngoại lệ này: stackoverflow.com/questions/9244185/
Lincoln

Lưu ý rằng Swing chỉ lỏng lẻo dựa trên MVC. Nó đã thu gọn View và Controller thành một lớp.
Matthias Braun

51
  1. Fly weight được sử dụng với một số giá trị của Byte, Short, Integer, Long và String.
  2. Mặt tiền được sử dụng ở nhiều nơi nhưng rõ ràng nhất là giao diện Scripting.
  3. Singleton - java.lang.R.78 xuất hiện trong tâm trí.
  4. Nhà máy trừu tượng - Cũng viết kịch bản và API JDBC.
  5. Lệnh - Hoàn tác / Làm lại của TextComponent.
  6. Trình thông dịch - API RegEx (java.util.regex. ) Và SQL (java.sql. ).
  7. Nguyên mẫu - Không chắc chắn 100% nếu tính này, nhưng tôi nghĩ clone()phương pháp này có thể được sử dụng cho mục đích này.

1
Liên quan đến mẫu Fly trọng : có thể là các Trình quản lý Bố cục java.awtjava.swinggói khác nhau . Thật vậy, chúng chia sẻ các thuộc tính nội tại gần như giống hệt nhau và các thuộc tính bên ngoài là các thành phần UI khác nhau mà chúng nằm ở dạng UI.
Vitaly

@NawaMan Bạn đã nói 5. Comand TextComponent's Undo / Redo. Tôi nghĩ rằng đó là memento không chỉ huy. Hoặc có lẽ là cả hai.
Mèo Tonerpson

Bạn có thể vui lòng giúp tôi trong một câu hỏi liên quan - stackoverflow.com/questions/61284856/ cấp . Tôi đã sử dụng mẫu lệnh trong ví dụ đơn giản này, nhưng tôi không chắc liệu đó có phải là cách đúng để giải quyết vấn đề của mình không.
Tom Joe

42

RMI dựa trên Proxy.

Có thể trích dẫn một mẫu cho hầu hết 23 mẫu trong GoF:

  1. Tóm tắt Factory: Các giao diện java.sql đều có các triển khai cụ thể từ JDBC JAR khi trình điều khiển được đăng ký.
  2. Trình tạo: java.lang.StringBuilder.
  3. Phương pháp nhà máy: Các nhà máy XML, trong số những người khác.
  4. Nguyên mẫu: Có thể là bản sao (), nhưng tôi không chắc là tôi sẽ mua nó.
  5. Đơn: java.lang.System
  6. Bộ điều hợp: Các lớp bộ điều hợp trong java.awt.event, ví dụ: WindowAd CHƯƠNG.
  7. Bridge: Các lớp sưu tập trong java.util. Danh sách được thực hiện bởi ArrayList.
  8. Tổng hợp: java.awt. java.awt.Component + java.awt.Container
  9. Trang trí: Tất cả trên gói java.io.
  10. Mặt tiền: ExternalContext hoạt động như một mặt tiền để thực hiện cookie, phạm vi phiên và các hoạt động tương tự.
  11. Flykg: Số nguyên, Nhân vật, v.v.
  12. Proxy: gói java.rmi
  13. Chuỗi trách nhiệm: Bộ lọc Servlet
  14. Lệnh: Mục menu swing
  15. Trình thông dịch: Không trực tiếp trong JDK, nhưng JavaCC chắc chắn sử dụng điều này.
  16. Trình lặp: giao diện java.util.Iterator; không thể rõ ràng hơn thế.
  17. Người hòa giải: JMS?
  18. Memento:
  19. Người quan sát: java.util.Observer/Observable (mặc dù rất tệ)
  20. Tiểu bang:
  21. Chiến lược:
  22. Bản mẫu:
  23. Khách thăm quan:

Tôi không thể nghĩ ra các ví dụ trong Java cho 10 trên 23, nhưng tôi sẽ xem liệu tôi có thể làm tốt hơn vào ngày mai không. Đó là những gì chỉnh sửa dành cho.


28

Mẫu Tóm tắt Factory được sử dụng ở nhiều nơi. Ví dụ DatagramSocketImplFactory, PreferencesFactory. Còn nhiều nữa --- tìm kiếm Javadoc cho các giao diện có chữ "Factory" trong tên của chúng.

Ngoài ra, có khá nhiều ví dụ về mẫu Factory.


22

Mặc dù tôi sắp xếp một chiếc đồng hồ bị hỏng với cái này, API Java XML sử dụng Factory rất nhiều. Ý tôi là chỉ cần nhìn vào cái này:

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);
String title = XPathFactory.newInstance().newXPath().evaluate("//title", doc);

...Vân vân và vân vân.

Ngoài ra, nhiều bộ đệm khác nhau (StringBuffer, ByteBuffer, StringBuilder) sử dụng Builder.


21

java.util.Collection # Iterator là một ví dụ hay về Phương thức Factory. Tùy thuộc vào lớp con cụ thể của Bộ sưu tập bạn sử dụng, nó sẽ tạo ra một triển khai Iterator. Bởi vì cả siêu lớp Factory (Bộ sưu tập) và Iterator được tạo đều là các giao diện, đôi khi nó bị nhầm lẫn với AbstractFactory. Hầu hết các ví dụ cho AbstractFactory trong câu trả lời được chấp nhận (BalusC) là các ví dụ về Factory , một phiên bản đơn giản của Phương thức Factory, không phải là một phần của các mẫu GoF gốc. Trong Facory, hệ thống phân cấp lớp Factory bị sụp đổ và nhà máy sử dụng các phương tiện khác để chọn sản phẩm được trả lại.

  • Nhà máy trừu tượng

Một nhà máy trừu tượng có nhiều phương pháp nhà máy, mỗi phương pháp tạo ra một sản phẩm khác nhau. Các sản phẩm được sản xuất bởi một nhà máy dự định sẽ được sử dụng cùng nhau (máy in và hộp mực của bạn tốt hơn là từ cùng một nhà máy (trừu tượng). Như đã đề cập trong các câu trả lời ở trên các họ của các thành phần GUI AWT, khác nhau từ nền tảng đến nền tảng, là một ví dụ về điều này (mặc dù cách triển khai của nó khác với cấu trúc được mô tả trong Gof).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.