มีรูปแบบการออกแบบที่ไม่จำเป็นในภาษาไดนามิกเช่น Python หรือไม่?


98

ฉันเริ่มอ่านหนังสือรูปแบบการออกแบบโดย GoF รูปแบบบางอย่างคล้ายกันมากกับความแตกต่างทางแนวคิดเล็กน้อย

คุณคิดว่าในหลาย ๆ รูปแบบบางอย่างนั้นไม่จำเป็นในภาษาไดนามิกเช่น Python (เช่นเพราะมันถูกแทนที่ด้วยคุณสมบัติแบบไดนามิก)?


1
ชนิดของคำถามที่น่าสนใจเนื่องจากมันบอกเป็นนัยว่าการเลือกภาษาสามารถใช้แทนการสร้างโค้ดได้อย่างมีประสิทธิภาพ
joshin4colours

3
ไม่ใช่คำตอบ แต่เกี่ยวข้อง - ฉันคิดว่ารูปแบบการออกแบบของ GoF นั้นมีความเกี่ยวข้องกับหลักการทั่วไปบางประการที่สามารถกลั่นออกมาได้สำหรับรูปแบบเฉพาะ ฉันไม่ได้หมายถึงแนวคิดของรูปแบบ (แม้ว่าจะมีความสำคัญอย่างยิ่ง) แต่ได้รับอนุญาตให้ใช้คลาสเพิ่มเติมในบางวิธีที่ละเมิดหลักการ OOP ที่ไร้เดียงสา ตัวอย่างเช่นมีรูปแบบมากมายที่ "รูปร่าง" ค่อนข้างชัดเจนไม่ได้ "วาดตัวเอง" หรืออย่างน้อยก็มอบหมายบางแง่มุมของงานให้กับวัตถุอื่น ฉันคิดว่าบทเรียนมีความสำคัญในภาษาใด ๆ ที่สนับสนุน OOP
Steve314

คำถามที่น่าสนใจมาก ฉันหวังว่าฉันจะสามารถ +5 แทน +1
MathAttack

1
สรุปรูปแบบการออกแบบที่ขาดคุณสมบัติทางภาษาและรูปแบบการออกแบบที่ขาดหายไปคุณสมบัติด้านภาษามากกว่าที่ c2 มันไม่ได้เป็นปัญหา 'ภาษาแบบไดนามิก' ตัวอย่างที่ง่ายที่สุดคือรูปแบบตัววนซ้ำซึ่งเป็นเรื่องเล็กน้อยใน python, perl (และแม้แต่ Java - ไม่ใช่แบบไดนามิก)

คำตอบ:


92

Peter Norvig แสดงให้เห็นว่ารูปแบบการออกแบบ 16 ใน 23 รูปแบบที่พบในหนังสือ GOF นั้นมองไม่เห็นหรือง่ายกว่าในภาษาแบบไดนามิก (เขาเน้นที่ Lisp และ Dylan)

เนื่องจากคุณพูดถึง Python มีการนำเสนอที่ดีโดย Alex Martelli เกี่ยวกับหัวข้อ นอกจากนี้ยังเกี่ยวข้องกับงูหลามมีการโพสต์บล็อกที่ดีแสดงให้เห็นถึงหกรูปแบบการออกแบบในหลามสำนวน

ฉันยังให้พื้นที่เก็บข้อมูล GitHub กับการใช้งาน (โดยคนอื่น) ของรูปแบบการออกแบบที่พบมากที่สุดในหลาม


ที่ดี! นั่นจะเป็นจุดตอบคำถาม :) ฉันอยากให้ทุกคนเข้าใจคำถามที่ชัดเจน
Gerenuk

2
ตาม Norvig, 2 ใน 16 (ล่ามและ Iterator) เป็น "มองไม่เห็นหรือเรียบง่าย" เนื่องจากมาโคร (ซึ่ง Python ไม่มี)
mjs

1
มันไม่ชัดเจนสำหรับฉันว่ารูปแบบเหล่านี้ไม่จำเป็นเพราะเสียงกระเพื่อมเป็นแบบไดนามิก แต่เป็นเพราะคุณสมบัติอื่น ๆ เช่นการเป็นภาษาที่ใช้งานได้ดี
jk

@mjs Iterators เป็นคุณลักษณะในตัวของ Python
Sakisk

1
นี้เป็นคำตอบที่ดีได้ดีขึ้นแม้เพียงเล็กน้อยโดยการเปลี่ยนคำอธิบายภาพการเชื่อมโยงความหมายค่อนข้างแสดงให้เห็นถึง , การนำเสนอและพื้นที่เก็บข้อมูล - พวกเขาอยู่ห่างไกลดีกว่าแล้วที่นี่แต่คุณรู้ว่า ... :-)
หมาป่า

59

ไม่จำเป็นต้องมีรูปแบบการออกแบบ ในทุกภาษา

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

รูปแบบการออกแบบมีอยู่เพื่อที่คุณจะได้สำนวนที่มีประโยชน์สำนวนที่มีประโยชน์เมื่อคุณเจอปัญหา แต่คุณไม่ควรใช้รูปแบบใด ๆ ก่อนที่จะระบุปัญหา Keep It Simple Stupidควรเป็นหลักการที่เหนือกว่าเสมอ

นอกจากนี้ยังช่วยให้คิดถึงรูปแบบการออกแบบเป็นแนวคิดในการคิดเกี่ยวกับปัญหาแทนที่จะเขียนโค้ดสำเร็จรูปที่เฉพาะเจาะจง และส่วนมากของแผ่นสำเร็จรูปเป็นวิธีแก้ปัญหากับ Java ขาดฟังก์ชั่นฟรีและวัตถุฟังก์ชั่นมาตรฐานที่คุณใช้ในภาษาอื่น ๆ ส่วนใหญ่ที่มีพวกเขา (เช่น Python, C #, C ++ ฯลฯ )

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

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


28
คำแถลงการเปิดของคุณมีความซับซ้อนอย่างมาก มันเป็นความจริงที่รูปแบบมีค่าใช้จ่ายดังนั้นไม่ควรใช้แบบสุ่มสี่สุ่มห้าเพื่อประโยชน์ของมัน แต่ในสถานที่ที่เหมาะสมพวกเขาสามารถช่วยได้มาก และใช่มันเป็นภาษาเฉพาะ - บางรูปแบบไม่จำเป็นในบางภาษาเพราะภาษานั้นรองรับวิธีการที่ดีกว่า แต่นั่นก็ยังห่างไกลจากข้อเรียกร้องการเปิดตัวของคุณ
PéterTörök

2
Btw Visitor ไม่ได้ถูกแทนที่ด้วยฟังก์ชั่นการสั่งซื้อที่สูงขึ้น - มันเป็นวิธีการแก้ปัญหาในการใช้การจัดส่งสองครั้งในภาษาที่ไม่สนับสนุนโดยพื้นฐาน (เช่น C # และ C ++) (และควรใช้อย่าง จำกัด เท่าที่ควร - ฉันคิดว่าเป็นหนึ่งในรูปแบบที่
แปลกประหลาด

14
คุณไม่จำเป็นต้องมีรูปแบบ สิ่งที่คุณต้องการก็คือการแก้ปัญหา หากคุณไม่ทราบรูปแบบใด ๆ เลยคุณยังคงสามารถแก้ปัญหาได้มันจะต้องใช้ความคิดมากขึ้นและคุณอาจคิดวิธีแก้ปัญหาที่ตรงกับรูปแบบบางอย่างหรือรูปแบบที่ไม่มี การรู้รูปแบบนั้นทำให้ง่ายขึ้น
Jan Hudec

3
@Gerenuk: ใช่ แต่ประเด็นก็คือรูปแบบที่ไม่เฉพาะภาษานั้นมีไว้สำหรับหัวของคุณ คุณมักจะพบว่ารูปแบบบางอย่างสามารถรับรู้ได้ง่ายขึ้นและใช้เครื่องมือที่แตกต่างกันในงูหลาม แต่มักจะมีแนวคิดเดียวกันอยู่
Jan Hudec

4
@ PéterTörök: ผู้เยี่ยมชมจะไม่ถูกแทนที่ด้วยสิ่งใด ประเด็นก็คือแนวคิดเดียวกันอาจถูกนำไปใช้โดยใช้เครื่องมือต่าง ๆ ในหลายกรณี แต่ฉันก็ยังถือว่ามันเป็นรูปแบบเดียวกัน
ม.ค. Hudec

13

รูปแบบนามธรรมของโรงงานนั้นไม่จำเป็นในภาษาที่พิมพ์ด้วยเป็ดเช่น Python เนื่องจากเป็นภาษาที่สร้างขึ้นจริง


10
คุณยังต้องการโรงงานที่แตกต่างกัน คุณไม่ต้องการคำจำกัดความอินเทอร์เฟซ
Stefano Borini

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

13

สิ่งเดียวที่อยู่ในใจคือรูปแบบซิงเกิล

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

ส่วนใหญ่ Singletons ใน python จะถูกแทนที่ด้วยโมดูล โมดูลในหลามนั้นมีลักษณะเป็น Singletons โดยธรรมชาติ หลามล่ามสร้างเหล่านี้ครั้งเดียวและครั้งเดียวเท่านั้น

รูปแบบอื่น ๆ ทั้งหมดใน Design Patters ที่ฉันใช้ใน Python พร้อมกันและคุณจะพบตัวอย่างของพวกมันทั่วทั้ง Python standard library และใน Python


2
นั่นไม่ใช่รูปแบบการต่อต้านในวันนี้จริงเหรอ?
Den

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

1
และในงูหลามเราไม่เคยใส่ใจเพราะมันไม่เคยมีปัญหาในการแก้
Martijn Pieters

1
"Python ไม่ได้บังคับให้คุณใช้วัตถุสำหรับทุกสิ่ง"ไม่จริง มันไม่ได้น่ารังเกียจเหมือนใน Java แต่ยังใน Python ทุกอย่างเป็นวัตถุ แม้โมดูลเป็นวัตถุ
vartec

3
@Darthfett: ฉันตระหนักดีถึงวิธีการlenทำงาน; กุยทำทางเลือกที่ชัดเจนที่นี่ ประเด็นของฉันคือแสดงให้เห็นว่า Python ไม่ใช่ภาษา OOP บริสุทธิ์ มันเป็นภาษาที่ใช้งานได้จริง ฉันชอบแบบนั้น.
Martijn Pieters

8

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

Python และการพิมพ์เป็ดโดยเฉพาะนั้นมีจุดสิ้นสุดเกี่ยวกับรูปแบบและแนวทางปฏิบัติทั่วไปมากมายและข้อ จำกัด มากมายที่ถูกกำหนดโดยรูปแบบบางอย่าง (ความเป็นส่วนตัวความไม่สามารถเปลี่ยนแปลงได้ ฯลฯ ) จะมีผลต่อโปรแกรมเมอร์ที่ตกลงจะไม่ทำลายมันเท่านั้น . แต่ยังคงพวกเขาจะทำงานเป็นเวลานานเป็นโปรแกรมเมอร์เล่นพร้อม ประตูยังคงเป็นประตูแม้ว่าจะถูกล้อมรอบด้วยกำแพงในจินตนาการ

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


นั่นน่าสนใจอย่างแน่นอน คุณคิดว่ารูปแบบใดที่คุณอาจลืมเพราะมีวิธีที่ดีกว่าใน Python
Gerenuk

4

หนังสือ "Design Patterns" ต้นฉบับมีการบันทึกและตั้งชื่อสำนวนทั่วไปที่มีประโยชน์ในภาษาเชิงวัตถุที่จำเป็นเช่น C ++ และ Smalltalk แต่ Smalltalk เป็นภาษาที่พิมพ์แบบไดนามิกดังนั้นจึงไม่สามารถเป็นเรื่องของการเป็นแบบไดนามิกได้

อย่างไรก็ตามคำตอบสำหรับคำถามของคุณยังคงเป็น "ใช่": บางรูปแบบการออกแบบเหล่านี้จะไม่เกี่ยวข้องกับภาษาที่พิมพ์แบบไดนามิกที่ทันสมัย โดยทั่วไปจะมีที่แตกต่างกันรูปแบบการออกแบบในภาษาที่แตกต่างโดยเฉพาะอย่างยิ่งในการที่แตกต่างกันชนิดของภาษา

หากต้องการย้ำ: "รูปแบบการออกแบบ" เป็นเพียงชื่อสำนวนการเขียนโปรแกรม: วิธีแก้ปัญหาทั่วไปสำหรับปัญหาที่พบบ่อย ภาษาที่ต่างกันต้องการสำนวนที่แตกต่างกันเพราะสิ่งที่เป็นปัญหาสำหรับภาษาหนึ่งอาจเป็นเรื่องเล็กน้อยสำหรับอีกภาษาหนึ่ง ในแง่นี้รูปแบบการออกแบบมีแนวโน้มที่จะชี้ให้เห็นจุดอ่อนในภาษาที่ใช้

ดังนั้นคุณอาจมองหาคุณสมบัติอื่น ๆ ที่ทำให้ภาษาแบบไดนามิกที่ทันสมัย ​​(หรือภาษาโบราณเช่น Lisp) มีประสิทธิภาพมากขึ้นทำให้การออกแบบรูปแบบคลาสสิกเหล่านี้ไม่เกี่ยวข้อง


1

รูปแบบการออกแบบเป็นวิธีการแก้ปัญหาเฉพาะ หากไม่พบปัญหารูปแบบการแก้ไขปัญหานั้นไม่มีประโยชน์

ผู้คนกำลังพยายามปรับรูปแบบการออกแบบทุกหนทุกแห่งราวกับว่าเป็นแนวทางปฏิบัติที่ดีที่สุดที่จะมีรูปแบบการออกแบบในโครงการของคุณ นั่นเป็นวิธีอื่น ๆ คุณพบปัญหาที่สามารถแก้ไขได้ด้วยรูปแบบจากโรงงานหรือไม่? เย็น. ปรับตัว อย่าค้นหารหัสของคุณและพยายามหาที่ที่เหมาะสมในการติดตั้งซิงเกิล (หรือจากโรงงานหรือด้านหน้าหรืออะไรก็ตาม ... )

บางที Python มีรูปแบบการออกแบบของตัวเองไม่พร้อมใช้งานสำหรับคน Java และ. NET (เนื่องจากลักษณะของภาษาเหล่านี้)?


1

ฉันจะบอกว่ารูปแบบขึ้นอยู่กับภาษาเสมอ รูปแบบหลามส่วนใหญ่นั้นดูเหมือนว่าที่กำหนดไว้ใน GoF เป็นเพราะ OOP ของ Python ที่กล่าวว่า OOP นั้นไม่เหมือนกับ OOP (ไม่มีสองภาษากำหนดวัตถุและการจัดการ 100% เหมือนกัน)

ดังนั้นจึงไม่ต้องสงสัยเลยว่ารูปแบบบางอย่างจะไม่สามารถใช้งานได้ "ตามที่เป็นอยู่" บางอย่างอาจไม่สมเหตุสมผลและมีรูปแบบบางอย่างที่อาจมีความหมายกับ Python เท่านั้น

ที่จะได้รับกลับมาตรงที่คำถามของคุณ: รูปแบบที่มีความจำเป็นเท่านั้นถ้าคุณต้องการให้พวกเขา คุณไม่จำเป็นต้องใช้มันหากไม่จำเป็นสำหรับพวกเขา

นอกจากนี้ยังมีรูปแบบมากกว่าที่กล่าวไว้ใน GoF ดูในวิกิพีเดียรูปแบบอื่น ๆ

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