อะไรคือความแตกต่างระหว่าง Facade และ Adapter Pattern?


108

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

ขอบคุณ

คำตอบ:


142

ซุ้มแบบหน้าวิกิพีเดียมีบันทึกสั้น ๆ เกี่ยวกับเรื่องนี้

"อะแดปเตอร์ถูกใช้เมื่อกระดาษห่อหุ้มต้องเป็นไปตามอินเทอร์เฟซเฉพาะและต้องรองรับพฤติกรรมหลายรูปแบบในทางกลับกันซุ้มจะถูกใช้เมื่อต้องการให้อินเทอร์เฟซที่ใช้งานง่ายขึ้นหรือง่ายขึ้น"

ฉันได้ยินการเปรียบเทียบว่าคุณควรนึกถึงรีโมทคอนโทรลสากลของคุณที่คุณได้ตั้งค่าให้ทำงานกับระบบสเตอริโอต่างๆของคุณโดยคุณกด "เปิด" และเปิดกล่องเคเบิลเครื่องรับและทีวีของคุณ อาจจะเป็นโฮมเธียเตอร์ที่หรูหราจริงๆและมันก็หรี่ไฟและดึงเฉดสีด้วย นั่นคือ Facade - ปุ่ม / ฟังก์ชันเดียวที่ดูแลชุดขั้นตอนที่ซับซ้อนมากขึ้น

รูปแบบอะแดปเตอร์เชื่อมโยงสองอินเทอร์เฟซที่เข้ากันไม่ได้

แก้ไข:การเปรียบเทียบอย่างรวดเร็วสำหรับรูปแบบอะแดปเตอร์ (ตามความคิดเห็น) อาจคล้ายกับอะแดปเตอร์ DVI-to-VGA การ์ดแสดงผลสมัยใหม่มักเป็น DVI แต่คุณมีจอภาพ VGA รุ่นเก่า ด้วยอะแดปเตอร์ที่เสียบเข้ากับอินพุต DVI ที่คาดไว้ของการ์ดแสดงผลของคุณและมีอินพุต VGA ของตัวเองคุณจะสามารถทำให้จอภาพเก่าของคุณทำงานร่วมกับการ์ดวิดีโอใหม่ได้


4
การเปรียบเทียบที่ยอดเยี่ยมโดยใช้รีโมทคอนโทรล คำอธิบายรูปแบบอะแดปเตอร์นั้นใช้ได้ แต่จะเป็นการดีที่จะเกิดการเปรียบเทียบแบบเดียวกัน
Kevin Le - Khnle

2
การเปรียบเทียบที่ยอดเยี่ยมแน่นอน! ตัวอย่าง Java ในโลกแห่งความเป็นจริงของรูปแบบ Adapter อาจช่วยให้เข้าใจได้ดีขึ้น: InputStreamReaderซึ่งปรับInputStreamให้เข้ากับReaderและOutputStreamWriterปรับOutputStreamให้เข้ากับWriterทั้งสองแบบซึ่งเป็นนามธรรมที่แตกต่างกัน
BalusC

1
@Khnle - รูปแบบอะแดปเตอร์ที่ใช้งานจริง: upload.wikimedia.org/wikipedia/commons/8/80/…
Eric Petroelje

@Khnle - เพิ่มในการเปรียบเทียบอะแดปเตอร์ (ขึ้นอยู่กับประสบการณ์ส่วนตัว) @Eric - ขอบคุณสำหรับแรงบันดาลใจและรูปที่ยอดเยี่ยม! @BalusC - ตัวอย่างการโทรที่ดีในโลกแห่งความเป็นจริง
awshepard

@BalusC - ฉันชอบตัวอย่างของคุณด้วย โชคดีที่ฉันรู้จัก Java @Eric Petroelje - รูปภาพมีค่านับพันคำ :-) @awshepard - ถ้าฉันไม่ได้เขียนโปรแกรมตอนนี้ฉันสามารถทำตามคำอธิบายของคุณได้ :-)
Kevin Le - Khnle

127

อะแดปเตอร์ == ทำให้หมุดสี่เหลี่ยมพอดีกับรูกลม

Facade == แผงควบคุมเดียวเพื่อเรียกใช้ส่วนประกอบภายในทั้งหมด


8
คำตอบนั้นถูกลดทอนความสมบูรณ์แบบ! ฉันรวมสิ่งนั้นไว้ในบันทึกแบบของฉัน :)
Joshua Dale

1
ความยิ่งใหญ่ในความเรียบง่าย
ผู้ชาย

20

จริงๆแล้วรูปแบบต่างๆสามารถนำไปใช้ในลักษณะเดียวกับทางโปรแกรมได้ - ความแตกต่างอยู่ที่เจตนา

รูปแบบการออกแบบอะแด็ปเตอร์มีไว้เพื่อ 'แปล' อินเทอร์เฟซของคลาสตั้งแต่หนึ่งคลาสขึ้นไปเป็นอินเทอร์เฟซที่ไคลเอ็นต์คาดว่าจะใช้ - อะแดปเตอร์จะแปลการเรียกไปยังอินเทอร์เฟซที่คาดไว้เป็นอินเทอร์เฟซจริงที่คลาสที่รวมไว้ใช้

รูปแบบ Facade ใช้เมื่อต้องการอินเทอร์เฟซที่เรียบง่ายกว่า (และอีกครั้งสามารถใช้งานได้ในลักษณะเดียวกันโดยการตัดชั้นเรียนที่ไม่เหมาะสม) คุณจะไม่บอกว่าคุณกำลังใช้ส่วนหน้าเมื่ออินเทอร์เฟซที่มีอยู่เข้ากันไม่ได้เมื่อคุณต้องการ เพื่อให้อ่านได้ง่ายขึ้นออกแบบมาไม่ดี ฯลฯ


19

ซุ้ม:

ประเด็นสำคัญ: (จากบทความjournaldevโดย Pankaj Kumar)

  1. รูปแบบด้านหน้าเป็นเหมือนตัวช่วยสำหรับแอปพลิเคชันไคลเอนต์
  2. รูปแบบซุ้มสามารถนำมาใช้ที่จุดของการพัฒนาใด ๆ มักจะเมื่อจำนวนของอินเตอร์เฟซการเจริญเติบโตและระบบซับซ้อน
  3. อินเทอร์เฟซระบบย่อยไม่รู้จัก Facade และไม่ควรมีการอ้างอิงใด ๆ ของอินเทอร์เฟซ Facade
  4. ควรใช้รูปแบบด้านหน้าสำหรับอินเทอร์เฟซที่คล้ายกันโดยมีวัตถุประสงค์เพื่อจัดเตรียมอินเทอร์เฟซเดียวแทนที่จะเป็นอินเทอร์เฟซหลายตัวที่ทำงานในประเภทเดียวกัน

แผนภาพชั้นด้านหน้า:

ป้อนคำอธิบายภาพที่นี่

อะแดปเตอร์:

  1. มันเป็นรูปแบบโครงสร้าง
  2. มีประโยชน์ในการทำงานกับอินเทอร์เฟซที่เข้ากันไม่ได้สองแบบ
  3. มันทำให้การทำงานของสิ่งหลังจากที่พวกเขากำลังออกแบบ

แผนภาพคลาสของอะแดปเตอร์:

ป้อนคำอธิบายภาพที่นี่

คุณสามารถดูรายละเอียดเพิ่มเติมเกี่ยวกับ Adapter ได้ในโพสต์ SE นี้:

ความแตกต่างระหว่างรูปแบบสะพานและรูปแบบอะแดปเตอร์

ความแตกต่างที่สำคัญ:

  1. ซุ้มกำหนดอินเตอร์เฟซใหม่ในขณะที่อะแดปเตอร์ใช้อินเตอร์เฟซเก่า อะแดปเตอร์ทำให้สองอินเทอร์เฟซที่มีอยู่ทำงานร่วมกันได้เมื่อเทียบกับการกำหนดอินเทอร์เฟซใหม่ทั้งหมด
  2. อะแดปเตอร์และ Facade เป็นทั้งเครื่องห่อหุ้ม แต่เป็นเครื่องห่อแบบต่างๆ จุดประสงค์ของ Facade คือการสร้างอินเทอร์เฟซที่ง่ายขึ้นและจุดประสงค์ของ Adapter คือการออกแบบให้เข้ากับอินเทอร์เฟซที่มีอยู่

มีลักษณะที่sourcemakingบทความเกินไปสำหรับความเข้าใจที่ดีขึ้น


ชอบดูไดอะแกรม! เพียงแค่ชี้แจงบางส่วนเมื่อฉันเปลี่ยนจำนวน / ประเภทของพารามิเตอร์หมายความว่ามันไม่ใช่ Adapter อีกต่อไปหรือไม่? like someMethod(int year, int month) ได้รับมอบหมายsomeMethod(DateTime start, DateTime end)หรือให้พูดว่าsomeMethod()delegated tosomeMethod(T param)
Jaime Sangcap

หากทั้งสองวิธีอยู่ในคลาสเดียวกันจะเรียกว่าการโอเวอร์โหลด หากพวกเขาอยู่ในคลาสที่แตกต่างกันก็สามารถเป็นอะแดปเตอร์ได้หากมีการใช้อะแดปเตอร์และอะแดปเตอร์ความสัมพันธ์
Ravindra babu

คำอธิบายที่ดีจริงๆ
Duc Filan

14

ซุ้มถูกออกแบบมาเพื่อจัดระเบียบบริการต่างๆหลังเกตเวย์บริการเดียว อะแด็ปเตอร์ได้รับการออกแบบมาเพื่อจัดเตรียมวิธีใช้อินเทอร์เฟซที่รู้จักเพื่อเข้าถึงอินเทอร์เฟซที่ไม่รู้จัก


11

วัตถุประสงค์ของก

ซุ้มคือความเรียบง่าย

อะแดปเตอร์คือการทำงานร่วมกัน


8

Facade มักจะตัดกับ Adapter

+--------------------------------------------------------------+-----------------------------------------------+
|                            Facade                            |                    Adapter                    |
+--------------------------------------------------------------+-----------------------------------------------+
| Simplifies multiple complex components with single interface | Provides differnet interface for an interface |
| Works with multiple components                               | Works with single component                   |
| Control panel is an example                                  | A power adapter is an example                 |
| High-level interface                                         | Low-level interface                           |
+--------------------------------------------------------------+-----------------------------------------------+

4

ตามปกติมีความคล้ายคลึงกันระหว่างรูปแบบต่างๆ แต่ฉันจะเห็นแบบนี้:

  • ซุ้มใช้ในการห่อหุ้มทั้งชั้นและเสนอวิธีการบางอย่างเพื่อเข้าถึง "สะดวก"
  • มีการใช้อะแด็ปเตอร์โดยที่คุณมีส่วนประกอบสองอย่างที่ควรทำงานร่วมกันได้อยู่แล้ว แต่ทำไม่ได้เพียงเพราะความแตกต่าง "ไม่สำคัญ" บางอย่างในอินเทอร์เฟซ

1
คำอธิบายที่ดี นี่เป็นครั้งแรกที่ฉันเจอคำว่า "ความแตกต่างที่ไม่สำคัญ" เมื่ออธิบายถึงอะแดปเตอร์ซึ่งเป็นเรื่องจริง
Sudara

4

ฉันจะพยายามอธิบายเป็นคำพูดธรรมดาโดยไม่ต้องมีพิธีรีตองมากนัก

ลองนึกภาพว่าคุณมีคลาสโดเมนและจาก UI ที่คุณต้องการโต้ตอบด้วย สามารถใช้ซุ้มเพื่อจัดเตรียมฟังก์ชันที่สามารถเรียกได้จากเลเยอร์ UI เพื่อให้เลเยอร์ UI ไม่ทราบเกี่ยวกับคลาสโดเมนใด ๆ นอกเหนือจากส่วนหน้า นั่นหมายความว่าแทนที่จะเรียกฟังก์ชันในคลาสโดเมนคุณจะเรียกใช้ฟังก์ชันเดียวจากส่วนหน้าซึ่งจะรับผิดชอบในการเรียกฟังก์ชันที่ต้องการจากคลาสอื่น ๆ

ในทางกลับกันอะแดปเตอร์สามารถใช้เพื่อรวมส่วนประกอบภายนอกอื่น ๆ ที่อาจมีฟังก์ชันการทำงานเหมือนกันที่คุณต้องการ แต่ฟังก์ชันเหล่านี้ไม่ได้ถูกเรียกในลักษณะเดียวกัน สมมติว่าคุณมีCarคลาสในโดเมนของคุณและคุณทำงานกับผู้ให้บริการรถยนต์ภายนอกที่มีการกำหนดคลาสรถยนต์ไว้ด้วย ในชั้นนี้คุณได้มีฟังก์ชั่นแต่ผู้ให้บริการภายนอกที่มีเทียบเท่าcar.getDoors() car.getNumDoors()คุณไม่ต้องการเปลี่ยนวิธีเรียกใช้ฟังก์ชันนี้ดังนั้นคุณสามารถใช้คลาสอะแด็ปเตอร์เพื่อรวมคลาส Car ภายนอกเพื่อให้การเรียกgetDoors()ของอะแด็ปเตอร์ถูกมอบหมายให้getNumDoors()กับคลาสภายนอก


3

รูปแบบอะแดปเตอร์อนุญาตให้สองอินเทอร์เฟซที่เข้ากันไม่ได้ก่อนหน้านี้สามารถทำงานร่วมกันได้ มี 2 ​​อินเทอร์เฟซแยกกันในการเล่น

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


3

อะแดปเตอร์ทำให้สองอินเทอร์เฟซทำงานร่วมกัน

Facade เปิดเผยคลาสเดียวไปสู่ระดับที่สูงขึ้นและ จำกัด มากขึ้น ตัวอย่างเช่นซุ้มโมเดลมุมมองอาจเปิดเผยคุณสมบัติอ่านอย่างเดียวของคลาสระดับล่างเท่านั้น


1

ซุ้ม

ความซับซ้อนของบทคัดย่อเพื่อให้อินเทอร์เฟซที่ง่ายขึ้น ตัวอย่างเช่นระบบปฏิบัติการคอมพิวเตอร์สรุปความซับซ้อนของฮาร์ดแวร์พื้นฐาน หรือภาษาโปรแกรมระดับสูง (Python / JavaScript) ทำให้เกิดความซับซ้อนเมื่อเปรียบเทียบกับภาษาระดับต่ำ (C)

อะแดปเตอร์

มันคล้ายกับอะแดปเตอร์ฮาร์ดแวร์ สมมติว่าคุณต้องการเชื่อมต่อUSB deviceกับ a serial portคุณจะต้องมีUSB-serial port adapterไฟล์.


1

รูปแบบอะแด็ปเตอร์เชื่อมโยงสองอินเทอร์เฟซที่เข้ากันไม่ได้โดยจัดเตรียมอินเทอร์เฟซใหม่

รูปแบบด้านหน้าช่วยลดความซับซ้อนของระบบย่อยที่ซับซ้อน (มีหลายองค์ประกอบ) ด้วยอินเทอร์เฟซเดียว


1

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

ก่อนอื่นฉันต้องการย้ำให้คนอื่นพูดที่นี่แล้วฉันจะเพิ่มหมายเหตุ:

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

ในทางกลับกันอะแดปเตอร์คือสิ่งห่อหุ้มรอบ ๆ บริการหรือวัตถุอื่น ทำให้วัตถุที่ถูกห่อเป็นไปตามอินเทอร์เฟซมาตรฐานที่ไคลเอ็นต์คาดหวัง สมมติว่ามีวิธีการในออบเจ็กต์ "บัญชีแยกประเภท" ซึ่งคุณต้องทำการปรับแต่ง (เปลี่ยนพารามิเตอร์เปลี่ยนชื่อ ฯลฯ ) คุณสามารถห่อด้วยอะแดปเตอร์

ตอนนี้ความแตกต่างอาจยังไม่ชัดเจน นั่นคือสิ่งที่ฉันต้องการนำเสนอความแตกต่างที่สำคัญระหว่างสองรูปแบบนี้โดยไม่มีที่ว่างสำหรับความสับสนเพิ่มเติม :

Facade ไม่เปลี่ยนรูปแบบโดเมนของระบบย่อยอื่นในขณะที่ Adapter ทำ นี่คือความแตกต่างที่สำคัญ ระยะเวลา

นั่นเป็นเหตุผลที่คุณรวมทั้งสองเมื่อคุณสร้างเลเยอร์ต่อต้านการทุจริต สมมติว่าคุณมีระบบย่อยที่คุณต้องการใช้ แต่คุณไม่ต้องการให้โมเดลโดเมนทำให้โมเดลโดเมนของคุณยุ่งเหยิง คุณจะทำอะไร? คุณจะสร้าง Anticorruption Layer อย่างไร? ก่อนอื่นคุณต้องสร้าง Facade ซึ่งจะช่วยลดความซับซ้อนในการเข้าถึงอินเทอร์เฟซสำหรับระบบย่อยจากนั้นอะแด็ปเตอร์สำหรับอ็อบเจ็กต์โดเมนที่ใช้ในอินเทอร์เฟซนั้น (โปรดจำไว้ว่าส่วนหน้ายังคงมีโมเดลโดเมนสำหรับระบบย่อยอื่น) ดังนั้นจึงสอดคล้องกับโมเดลของคุณ

รูปแบบการออกแบบจำนวนมากสามารถใช้ในการสร้างแบบจำลองโดเมน นี่เป็นเรื่องจริงสำหรับรูปแบบการออกแบบ Facade และ Adapter เช่นกัน แม้ว่าความแตกต่างระหว่างสองรูปแบบนี้อาจไม่ชัดเจนในขอบเขต "รูปแบบการออกแบบ" แต่ก็มีความชัดเจนมากขึ้นในขอบเขต "การสร้างแบบจำลองโดเมน"


0

ฉันอ่านคำจำกัดความทั้งสองคำมาแล้วและดูเหมือนจะค่อนข้างเหมือนกัน

เหรอ?

ฉันสังเกตเห็นว่าบางครั้งคำว่าAdapterถูกใช้เพื่ออธิบายสิ่งที่เป็นจริงStategyอาจเป็นเพราะคำนี้มีความหมายมากกว่า

ยกตัวอย่างเช่นในZend Frameworkทั้งหมดอะแดปเตอร์ชั้นเรียนในการใช้งานจริงของกลยุทธ์รูปแบบเพราะพวกเขาเพียงห่อรหัสพื้นเมืองที่อยู่เบื้องหลังการเรียนที่จะมีพฤติกรรมหลาย

มักใช้อะแดปเตอร์เพื่อห่อหุ้มโค้ดแบบเดิมหรือ "แบบเก่า"


0

เป้าหมายหลักของรูปแบบFacadeคือการทำให้คลาสหรือระบบย่อยใช้งานง่ายขึ้นในขณะที่เป้าหมายหลักของรูปแบบAdapterคือการปรับอินเทอร์เฟซให้เป็นไปตามที่ลูกค้าคาดหวัง

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