ตัวอย่างของรูปแบบการออกแบบ GoF ในไลบรารีหลักของ Java


672

ฉันกำลังเรียนรู้รูปแบบการออกแบบ Java ของ GoF และฉันต้องการเห็นตัวอย่างชีวิตจริงของพวกเขา ตัวอย่างที่ดีของรูปแบบการออกแบบเหล่านี้ในไลบรารีหลักของ Java คืออะไร

คำตอบ:


3229

คุณสามารถค้นหาภาพรวมของจำนวนมากของรูปแบบการออกแบบในวิกิพีเดีย นอกจากนี้ยังกล่าวถึงรูปแบบที่กล่าวถึงโดย GoF ฉันจะสรุปพวกเขาที่นี่และพยายามกำหนดรูปแบบการนำไปใช้ให้มากที่สุดเท่าที่จะทำได้พบได้ทั้งใน Java SE และ Java EE API


รูปแบบ Creational

บทคัดย่อจากโรงงาน (รู้จักได้โดยวิธีการสร้างที่ส่งคืนตัวโรงงานซึ่งสามารถนำมาใช้เพื่อสร้างประเภทนามธรรม / อินเทอร์เฟซอื่น)

ตัวสร้าง (รู้จักได้โดยวิธีการสร้างที่คืนค่าอินสแตนซ์เอง)

วิธีการจากโรงงาน (สามารถรับรู้ได้โดยวิธีการสร้างสรรค์ที่ส่งคืนการใช้งานนามธรรม / ประเภทอินเตอร์เฟส)

ต้นแบบ (recognizeable โดยวิธี Creational กลับแตกต่างกันตัวอย่างของตัวเองที่มีคุณสมบัติเดียวกัน)

ซิงเกิล (รู้จักได้โดยวิธีการสร้างที่ส่งคืนอินสแตนซ์เดียวกัน (โดยปกติจะเป็นของตัวเอง) ทุกครั้ง)


รูปแบบโครงสร้าง

อะแด็ปเตอร์ (รู้จักได้โดยวิธีการสร้างโดยใช้อินสแตนซ์ของบทคัดย่อ / ประเภทอินเตอร์เฟสที่แตกต่างกันและส่งคืนการนำไปใช้ของตัวเอง / อีกประเภทนามธรรม / อินเทอร์เฟซที่ตกแต่ง / แทนที่อินสแตนซ์ที่กำหนด)

Bridge (รู้จักได้โดยวิธีการสร้างโดยใช้อินสแตนซ์ของบทคัดย่อ / ประเภทอินเตอร์เฟสที่แตกต่างกันและคืนค่าการนำนามธรรม / อินเตอร์เฟสประเภทที่ผู้มอบหมาย / ใช้อินสแตนซ์ที่กำหนด)

  • ยังไม่มีใครนึกถึง ตัวอย่างที่สมมติขึ้นจะnew LinkedHashMap(LinkedHashSet<K>, List<V>)ส่งคืนแผนที่ที่เชื่อมโยงซึ่งไม่สามารถแก้ไขได้ซึ่งไม่ได้คัดลอกรายการ แต่ใช้พวกมัน java.util.Collections#newSetFromMap()และsingletonXXX()วิธีการอย่างไรมาใกล้เคียง

คอมโพสิต (recognizeable โดยวิธีการพฤติกรรมการใช้อินสแตนซ์ของเดียวกันประเภท / อินเตอร์เฟซที่เป็นนามธรรมในโครงสร้างต้นไม้)

มัณฑนากร (recognizeable โดยวิธีการ Creational ตัวอย่างของเดียวกันประเภทนามธรรม / อินเตอร์เฟซที่เพิ่มพฤติกรรมเพิ่มเติม)

ซุ้ม (recognizeable พฤติกรรมโดยวิธีการซึ่งภายในใช้อินสแตนซ์ที่แตกต่างกันเป็นอิสระประเภทนามธรรม / อินเตอร์เฟซ)

Flyweight (รู้จักได้โดยวิธีการสร้างที่ส่งคืนอินสแตนซ์ที่แคชไว้เล็กน้อยแนวคิด "multiton")

พร็อกซี (จำได้ด้วยวิธีการสร้างที่ส่งกลับการดำเนินการของนามธรรม / ประเภทอินเตอร์เฟสซึ่งในทางกลับกันได้รับมอบหมาย / ใช้การดำเนินการที่แตกต่างกันของนามธรรม / ประเภทอินเตอร์เฟสที่กำหนด)


รูปแบบพฤติกรรม

ห่วงโซ่ของความรับผิดชอบ (recognizeable โดยวิธีการซึ่งพฤติกรรม (อ้อม) เรียกวิธีการเดียวกันในอีกการดำเนินการเดียวกันประเภท / อินเตอร์เฟซที่เป็นนามธรรมในคิว)

คำสั่ง (จำได้ด้วยวิธีพฤติกรรมในนามธรรม / ประเภทอินเตอร์เฟสซึ่งเรียกใช้วิธีการในการดำเนินการประเภทนามธรรม / อินเตอร์เฟซที่แตกต่างกันซึ่งได้รับการห่อหุ้มโดยการใช้คำสั่งในระหว่างการสร้าง)

ล่าม (recognizeable โดยวิธีพฤติกรรมกลับโครงสร้างอินสแตนซ์ที่แตกต่างกัน / ประเภทที่กำหนดเช่น / ประเภท; ทราบว่าแยก / การจัดรูปแบบไม่ได้เป็นส่วนหนึ่งของรูปแบบการกำหนดรูปแบบและวิธีการที่จะใช้มันเป็น)

Iterator (รู้จักได้โดยวิธีการตามพฤติกรรมที่ส่งคืนอินสแตนซ์ของประเภทที่แตกต่างจากคิว)

ผู้ไกล่เกลี่ย (รู้จักได้โดยวิธีพฤติกรรมที่ใช้อินสแตนซ์ของบทคัดย่อ / ประเภทอินเตอร์เฟสที่แตกต่างกัน (มักใช้รูปแบบคำสั่ง) ซึ่งมอบหมาย / ใช้อินสแตนซ์ที่กำหนด)

ที่ระลึก (จำได้ด้วยวิธีการพฤติกรรมซึ่งเปลี่ยนสถานะภายในของอินสแตนซ์ทั้งหมด )

สังเกตการณ์ (หรือเผยแพร่ / สมัครสมาชิก) (recognizeable พฤติกรรมโดยวิธีการซึ่งเรียกวิธีการในตัวอย่างของอีกประเภท / อินเตอร์เฟซที่เป็นนามธรรมขึ้นอยู่กับสถานะของตัวเอง)

รัฐ (จำได้ด้วยวิธีพฤติกรรมซึ่งเปลี่ยนพฤติกรรมของมันขึ้นอยู่กับสถานะของอินสแตนซ์ซึ่งสามารถควบคุมได้จากภายนอก)

กลยุทธ์ (รู้จักได้โดยวิธีพฤติกรรมในนามธรรม / ประเภทอินเตอร์เฟสซึ่งเรียกใช้วิธีในการใช้งานบทคัดย่อ / ประเภทอินเตอร์เฟสที่แตกต่างกันซึ่งได้รับการส่งผ่านเป็นอาร์กิวเมนต์วิธีในการใช้กลยุทธ์)

  • java.util.Comparator#compare()Collections#sort()ดำเนินการโดยหมู่คนอื่น ๆ
  • javax.servlet.http.HttpServlet, service()และdoXXX()วิธีการทั้งหมดใช้HttpServletRequestและHttpServletResponseและผู้ดำเนินการต้องดำเนินการ (และไม่ให้ถือเป็นตัวแปรอินสแตนซ์!)
  • javax.servlet.Filter#doFilter()

แม่แบบวิธี (จำได้ด้วยวิธีพฤติกรรมซึ่งมีพฤติกรรม "เริ่มต้น" ที่กำหนดโดยประเภทนามธรรมแล้ว)

ผู้เข้าชม (สามารถรับรู้ได้โดยนามธรรม / ประเภทอินเตอร์เฟสที่แตกต่างกันซึ่งมีวิธีการที่กำหนดซึ่งใช้ประเภทนามธรรม / อินเตอร์เฟซอื่น ๆหนึ่งจริงเรียกวิธีการของอื่น ๆ และอื่น ๆ ดำเนินการกลยุทธ์ที่ต้องการมัน)


23
ประทับใจ .. :) +1 javax.lang.model.elementกำหนดผู้เยี่ยมชม;) ฉันไม่แน่ใจว่าdoXXXและdoFilterเป็น "กลยุทธ์" หรือไม่
Bozho

16
ผู้สร้างที่กล่าวถึงเช่น StrinbgBuilder ไม่ใช่ตัวอย่างสำหรับ Builder-Pattern มันเป็นความผิดพลาดที่พบบ่อยมาก แต่ที่จะต้องพิจารณาพวกเขาเป็นผู้สร้าง (เพื่อให้คุณไม่ได้จริงๆจะให้โทษ ^ _ ^)
แองเจิล O'Sphere

77
@ BalusC ฉันมีคำถามที่จะถามคุณ คุณอ่านซอร์สโค้ดWHOLEของ Java และ JSF หรือไม่
Tapas Bose

20
@ Tapas: ฉันไม่ได้อ่านทุกอย่างมีเพียงบางส่วนที่ฉันต้องการหรืออยากรู้ว่า "พวกเขา" ทำได้อย่างไร
BalusC

7
ตัวอย่างส่วนใหญ่ภายใต้ "วิธีการของโรงงาน" เป็นตัวอย่างของ "โรงงานแบบคงที่" ซึ่งไม่ใช่รูปแบบ GoF ไม่ถูกต้อง.
ผู้ถือแหวน

107
  1. แบบสังเกตการณ์ตลอดทั้งวงสวิง ( Observable, Observer)
  2. MVC ยังอยู่ในการแกว่ง
  3. รูปแบบอะแดปเตอร์: InputStreamReader และ OutputStreamWriter หมายเหตุ: ContainerAdapter, ComponentAdapter, FocusAdapter, KeyAdapter, MouseAdapterมีไม่ได้อะแดปเตอร์; พวกเขาเป็นวัตถุ Null ตัวเลือกการตั้งชื่อแย่โดยซัน
  4. รูปแบบมัณฑนากร ( BufferedInputStreamสามารถตกแต่งสตรีมอื่น ๆ เช่นFilterInputStream)
  5. รูปแบบ AbstractFactory สำหรับชุดเครื่องมือ AWT และคลาสรูปลักษณ์และความรู้สึกที่เสียบได้
  6. java.lang.Runtime#getRuntime() คือซิงเกิล
  7. ButtonGroup สำหรับรูปแบบคนกลาง
  8. Action, AbstractActionอาจจะใช้สำหรับการแสดงภาพที่แตกต่างกันในการดำเนินการรหัสเดียวกัน -> รูปแบบคำสั่ง
  9. Interned Strings หรือ CellRender ใน JTable สำหรับรูปแบบ Flyweight (คิดเกี่ยวกับกลุ่มต่าง ๆ เช่นกลุ่มเธรดพูลกลุ่มการเชื่อมต่อกลุ่มวัตถุ EJB - ฟลายเวทคือการจัดการทรัพยากรที่ใช้ร่วมกันจริงๆ)
  10. โมเดลเหตุการณ์ Java 1.0 เป็นตัวอย่างของ Chain of Responsibility เช่นเดียวกับ Servlet Filters
  11. รูปแบบตัววนซ้ำใน Collections Framework
  12. คอนเทนเนอร์ที่ซ้อนใน AWT / Swing ใช้รูปแบบคอมโพสิต
  13. ผู้จัดการโครงร่างใน AWT / Swing เป็นตัวอย่างของกลยุทธ์

และอีกมากมายฉันเดา


1
ขอบคุณสำหรับเคล็ดลับใน MouseAdapter ฉันพบ exaplanation นี้: stackoverflow.com/questions/9244185/…
ลินคอล์น

โปรดทราบว่าการแกว่งนั้นอิงจาก MVC เพียงอย่างเดียว มันได้ยุบ View และ Controller ลงในคลาสเดียว
Matthias Braun

51
  1. Flyweightใช้กับค่าบางค่าของ Byte, Short, Integer, Long และ String
  2. Facadeถูกใช้ในหลาย ๆ ที่ แต่ที่ชัดเจนที่สุดคือ Interface Scripting
  3. Singleton - java.lang.Runtime อยู่ในใจ
  4. Abstract Factory - การเขียนสคริปต์และ JDBC API
  5. คำสั่ง - เลิกทำ / ทำซ้ำของ TextComponent
  6. Interpreter - RegEx (java.util.regex. ) และ SQL (java.sql. ) API
  7. ต้นแบบ - ไม่แน่ใจ 100% ถ้านับนี้ แต่ฉันคิดว่าclone()วิธีg สามารถนำมาใช้เพื่อจุดประสงค์นี้

1
เกี่ยวกับรูปแบบFlyweight : อาจเป็นตัวจัดการเลย์เอาต์ที่แตกต่างจากjava.awtและjava.swingแพ็คเกจ อันที่จริงพวกเขาแบ่งปันคุณสมบัติที่แท้จริงที่เหมือนกันเกือบและคุณลักษณะภายนอกเป็นองค์ประกอบ UI ที่แตกต่างกันที่พวกเขาวางในรูปแบบ UI
Vitaly

@NawaMan คุณพูดว่า 5. Unand Uno / Redo ฉันคิดว่ามันเป็นของที่ระลึกไม่สั่ง หรืออาจเป็นได้ทั้ง
Stimpson Cat

คุณช่วยฉันในคำถามที่เกี่ยวข้อง - stackoverflow.com/questions/61284856/... ฉันใช้รูปแบบคำสั่งในตัวอย่างง่ายๆนี้ แต่ฉันไม่แน่ใจว่าเป็นวิธีที่เหมาะสมในการแก้ปัญหาของฉันหรือไม่
Tom Joe

42

RMI ขึ้นอยู่กับพร็อกซี

ควรเป็นไปได้ที่จะกล่าวถึงรูปแบบหนึ่งใน 23 รูปแบบส่วนใหญ่ใน GoF:

  1. Abstract Factory: อินเตอร์เฟส java.sql ทั้งหมดได้รับการปรับใช้อย่างเป็นรูปธรรมจาก JDBC JAR เมื่อลงทะเบียนไดรเวอร์
  2. Builder: java.lang.StringBuilder
  3. วิธีการของโรงงาน: โรงงาน XML และอื่น ๆ
  4. ต้นแบบ: อาจจะโคลนนิ่ง () แต่ฉันไม่แน่ใจว่าฉันจะซื้อมัน
  5. Singleton: java.lang.System
  6. อะแดปเตอร์: คลาสอะแดปเตอร์ใน java.awt.event เช่น WindowAdapter
  7. Bridge: คลาสของคอลเล็กชันใน java.util รายการที่นำมาใช้โดย ArrayList
  8. คอมโพสิต: java.awt java.awt.Component + java.awt.Container
  9. มัณฑนากร: ทั่วทุกแพคเกจ java.io
  10. Facade: ExternalContextทำหน้าที่เป็นส่วนหน้าสำหรับการทำคุกกี้ขอบเขตเซสชันและการดำเนินการที่คล้ายกัน
  11. Flyweight: จำนวนเต็มตัวละคร ฯลฯ
  12. พร็อกซี: แพคเกจ java.rmi
  13. เครือข่ายความรับผิดชอบ: ตัวกรอง Servlet
  14. คำสั่ง: รายการเมนูสวิง
  15. ล่าม: ไม่โดยตรงใน JDK แต่ JavaCC ใช้สิ่งนี้อย่างแน่นอน
  16. Iterator: อินเตอร์เฟส java.util.Iterator; ไม่สามารถชัดเจนกว่านั้น
  17. สื่อกลาง: JMS?
  18. Memento:
  19. ผู้สังเกตการณ์: java.util.Observer/Observable (ทำได้ไม่ดี)
  20. สถานะ:
  21. กลยุทธ์:
  22. แม่แบบ:
  23. ผู้เข้าชม:

ฉันไม่สามารถคิดถึงตัวอย่างใน Java สำหรับ 10 จาก 23 แต่ฉันจะดูว่าฉันจะทำได้ดีขึ้นในวันพรุ่งนี้ นั่นคือสิ่งที่แก้ไขสำหรับ


28

รูปแบบนามธรรมของโรงงานถูกนำมาใช้ในสถานที่ต่าง ๆ DatagramSocketImplFactoryเช่น PreferencesFactory, มีอีกมากมาย --- ค้นหา Javadoc สำหรับอินเทอร์เฟซที่มีคำว่า "โรงงาน" ในชื่อ

นอกจากนี้ยังมีรูปแบบ Factory ค่อนข้างน้อยเช่นกัน


22

แม้ว่าฉันจะเรียงลำดับของนาฬิกาแตกหัก แต่ Java XML API ก็ใช้ Factory เป็นจำนวนมาก ฉันหมายถึงเพียงแค่ดูที่:

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

...และอื่น ๆ และอื่น ๆ.

นอกจากนี้ยังมีตัวสร้างบัฟเฟอร์ (StringBuffer, ByteBuffer, StringBuilder) ที่หลากหลาย


21

java.util.Collection # Iterator เป็นตัวอย่างที่ดีของวิธีการของโรงงาน ขึ้นอยู่กับคลาสย่อยที่เป็นรูปธรรมของคอลเล็กชันที่คุณใช้มันจะสร้างการใช้ Iterator เนื่องจากทั้งโรงงาน superclass (คอลเลกชัน) และ Iterator ที่สร้างขึ้นเป็นอินเตอร์เฟสบางครั้งจึงสับสนกับ ตัวอย่างส่วนใหญ่สำหรับ AbstractFactory ในคำตอบที่ได้รับการยอมรับ (BalusC) เป็นตัวอย่างของFactoryซึ่งเป็นเวอร์ชันของวิธีการในโรงงานที่ไม่ซับซ้อนซึ่งไม่ได้เป็นส่วนหนึ่งของรูปแบบ GoF ดั้งเดิม ใน Facory ลำดับชั้นคลาสของโรงงานจะถูกยุบและโรงงานใช้วิธีการอื่นเพื่อเลือกผลิตภัณฑ์ที่จะส่งคืน

  • โรงงานบทคัดย่อ

โรงงานที่เป็นนามธรรมมีวิธีการที่หลากหลายจากโรงงาน ผลิตภัณฑ์ที่ผลิตโดยโรงงานหนึ่งมีวัตถุประสงค์เพื่อใช้ร่วมกัน (เครื่องพิมพ์และตลับหมึกของคุณที่ดีกว่ามาจากโรงงานเดียวกัน (นามธรรม)) ดังที่ได้กล่าวไว้ในคำตอบข้างต้นตระกูลของส่วนประกอบ AWT GUI ที่แตกต่างจากแพลตฟอร์มหนึ่งไปอีกแพลตฟอร์มเป็นตัวอย่างของสิ่งนี้ (แม้ว่าการนำไปปฏิบัติจะแตกต่างจากโครงสร้างที่อธิบายไว้ใน Gof)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.