ออกแบบรูปแบบเพื่อหลีกเลี่ยง [ปิด]


105

หลายคนดูเหมือนจะเห็นด้วยว่ารูปแบบ Singleton มีข้อบกพร่องหลายประการและบางคนแนะนำให้หลีกเลี่ยงรูปแบบทั้งหมด มีความเป็นการอภิปรายที่ยอดเยี่ยมที่นี่ กรุณาแสดงความคิดเห็นเกี่ยวกับรูปแบบ Singleton สำหรับคำถามนั้น

คำถามของฉัน : มีรูปแบบการออกแบบอื่น ๆ ที่ควรหลีกเลี่ยงหรือใช้อย่างระมัดระวังหรือไม่?


ฉันต้องแจ้งให้ทราบเกี่ยวกับรายการที่ยอดเยี่ยมของ Design Antipatterns deviq.com/antipatterns
พัฒนา

@casperOne ทำไมคุณปิดคำถาม? คำถามถูกต้องตามกฎหมาย
bleepzter

คำตอบ:


149

รูปแบบมีความซับซ้อน

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

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

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

หลักการมากกว่ารูปแบบ

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

มีหลักการออกแบบมากมาย แต่ที่อธิบายไว้ในบทแรกของหนังสือ GoFนั้นค่อนข้างมีประโยชน์ในการเริ่มต้น

  • โปรแกรมเป็น 'อินเทอร์เฟซ' ไม่ใช่ 'การนำไปใช้งาน' (แก๊งโฟร์ 2538: 18)
  • ชอบ 'องค์ประกอบของวัตถุ' มากกว่า 'การสืบทอดคลาส' (แก๊งโฟร์ 2538: 20)

ปล่อยให้คนเหล่านั้นจมอยู่กับคุณสักพัก ควรสังเกตว่าเมื่อ GoF ถูกเขียนอินเทอร์เฟซหมายถึงอะไรก็ตามที่เป็นนามธรรม (ซึ่งหมายถึงคลาสซุปเปอร์ด้วย) เพื่อไม่ให้สับสนกับอินเทอร์เฟซเป็นประเภทใน Java หรือ C # หลักการที่สองมาจากการใช้มากเกินไปสังเกตของมรดกซึ่งเป็นเศร้าทั่วไปวันนี้ยังคง

จากนั้นคุณสามารถอ่านข้อมูลเกี่ยวกับหลักการ SOLIDซึ่งเป็นที่รู้จักกันโดยโรเบิร์ตเซซิลมาร์ติน(aka. ลุงบ๊อบ) Scott Hanselman สัมภาษณ์ลุงบ็อบในพอดคาสต์เกี่ยวกับหลักการเหล่านี้ :

  • S ingle หลักการความรับผิดชอบ
  • Oปากกาปิดหลักการ
  • หลักการเปลี่ยนตัวL iskov
  • I nterface หลักการแยก
  • D ependency Inversion Principle

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


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

21

สิ่งที่ผู้เขียนรูปแบบการออกแบบกังวลมากที่สุดคือรูปแบบ "ผู้เยี่ยมชม"

มันเป็น "ความชั่วร้ายที่จำเป็น" แต่มักจะถูกใช้มากเกินไปและความจำเป็นในการใช้มันมักจะเผยให้เห็นข้อบกพร่องพื้นฐานในการออกแบบของคุณ

ชื่ออื่นสำหรับรูปแบบ "ผู้เยี่ยมชม" คือ "การจัดส่งหลายรายการ" เนื่องจากรูปแบบผู้เยี่ยมชมคือสิ่งที่คุณลงท้ายด้วยเมื่อคุณต้องการใช้ภาษา OO สำหรับการจัดส่งประเภทเดียวเพื่อเลือกรหัสที่จะใช้ตามประเภทของสองประเภท (หรือมากกว่า) วัตถุที่แตกต่างกัน

ตัวอย่างคลาสสิกคือคุณมีจุดตัดระหว่างสองรูปร่าง แต่มีกรณีที่ง่ายกว่าที่มักถูกมองข้ามนั่นคือการเปรียบเทียบความเท่าเทียมกันของวัตถุสองชิ้นที่ต่างกัน

อย่างไรก็ตามบ่อยครั้งที่คุณจบลงด้วยสิ่งนี้:

interface IShape
{
    double intersectWith(Triangle t);
    double intersectWith(Rectangle r);
    double intersectWith(Circle c);
}

ปัญหาคือคุณได้ใช้ "IShape" ร่วมกันทั้งหมด คุณบอกเป็นนัยว่าเมื่อใดก็ตามที่คุณต้องการเพิ่มรูปร่างใหม่ในลำดับชั้นคุณจะต้องเปลี่ยนการใช้งาน "รูปร่าง" อื่น ๆ ทั้งหมดด้วย

บางครั้งนี่เป็นการออกแบบที่เรียบง่าย แต่คิดให้ดี ไม่ออกแบบของคุณจริงๆเอกสารที่คุณจำเป็นต้องจัดส่งในสองประเภท? คุณยินดีที่จะเขียนการระเบิดหลายวิธีร่วมกันหรือไม่?

บ่อยครั้งโดยการแนะนำแนวคิดอื่นคุณสามารถลดจำนวนชุดค่าผสมที่คุณจะต้องเขียน:

interface IShape
{
    Area getArea();
}

class Area
{
    public double intersectWith(Area otherArea);
    ...
}

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


2
เมื่อพูดถึงผู้เยี่ยมชมแล้วลุงบ๊อบใช้มัน "ตลอดเวลา" butunclebob.com/ArticleS.UncleBob.IuseVisitor
Spoike

3
@Paul Hollingsworth คุณช่วยอ้างอิงได้ไหมว่าผู้เขียน Design Patterns กังวล (และทำไมพวกเขาถึงกังวล)
m3th0dman

16

Singletons - คลาสที่ใช้ singleton X มีการพึ่งพาซึ่งยากที่จะมองเห็นและยากที่จะแยกออกสำหรับการทดสอบ

มักใช้บ่อยมากเพราะสะดวกและเข้าใจง่าย แต่อาจทำให้การทดสอบซับซ้อนขึ้นได้

ดูSingletons มีพยาธิสภาพโกหก


1
พวกเขายังสามารถทดสอบได้อย่างง่ายดายเนื่องจากสามารถให้จุดเดียวในการฉีดวัตถุจำลอง ทั้งหมดขึ้นอยู่กับการปรับสมดุลให้ถูกต้อง
Martin Brown

1
@Martin: หากแน่นอนเป็นไปได้ที่จะเปลี่ยน singelton สำหรับการทดสอบ (ถ้าคุณไม่ได้ใช้การใช้งาน singelton มาตรฐาน) แต่จะง่ายกว่าการผ่านการทดสอบในตัวสร้างอย่างไร?
orip

14

ฉันเชื่อว่ารูปแบบวิธีเทมเพลตโดยทั่วไปเป็นรูปแบบที่อันตรายมาก

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

2
ฉันจะเพิ่มว่าเมื่อใดก็ตามที่คุณใช้ Template Method คุณอาจจะใช้ Strategy ได้ดีกว่า ปัญหาของ TemplateMethod คือมีการจัดเรียงซ้ำระหว่างคลาสพื้นฐานและคลาสที่ได้รับซึ่งมักจะอยู่คู่กันมากเกินไป
Paul Hollingsworth

5
@Paul: วิธีเทมเพลตนั้นยอดเยี่ยมเมื่อใช้อย่างเหมาะสมกล่าวคือเมื่อชิ้นส่วนที่แตกต่างกันไปจำเป็นต้องรู้มากเกี่ยวกับส่วนที่ไม่ได้ สิ่งที่ฉันใช้คือควรใช้กลยุทธ์เมื่อโค้ดพื้นฐานเรียกเฉพาะโค้ดที่กำหนดเองและวิธีเทมเพลตควรใช้เมื่อโค้ดที่กำหนดเองจำเป็นต้องรู้เกี่ยวกับโค้ดพื้นฐาน
dsimcha

ใช่ dsimcha ฉันเห็นด้วย ... ตราบใดที่นักออกแบบชั้นเรียนรู้เรื่องนี้
Paul Hollingsworth

9

ฉันไม่คิดว่าคุณควรหลีกเลี่ยงรูปแบบการออกแบบ (DP) และฉันไม่คิดว่าคุณควรบังคับตัวเองให้ใช้ DP เมื่อวางแผนสถาปัตยกรรมของคุณ เราควรใช้ DP เฉพาะเมื่อมันเกิดจากการวางแผนของเราเท่านั้น

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

สิ่งหนึ่งที่เราไม่ควรทำคือถือว่า DP เป็นเอนทิตีที่ไม่เปลี่ยนรูปเราควรปรับรูปแบบให้เข้ากับความต้องการของเรา

ดังนั้นการสรุปฉันไม่คิดว่าเราควรหลีกเลี่ยง DPs เราควรยอมรับพวกเขาเมื่อพวกเขามีรูปร่างในสถาปัตยกรรมของเราแล้ว


7

ฉันคิดว่า Active Record เป็นรูปแบบที่ใช้มากเกินไปซึ่งกระตุ้นให้เกิดการผสมผสานตรรกะทางธุรกิจกับรหัสต่อเนื่อง มันไม่ได้ผลดีนักในการซ่อนการใช้งานพื้นที่เก็บข้อมูลจากเลเยอร์โมเดลและเชื่อมโยงโมเดลเข้ากับฐานข้อมูล มีทางเลือกมากมาย (อธิบายไว้ใน PoEAA) เช่น Table Data Gateway, Row Data Gateway และ Data Mapper ซึ่งมักจะเป็นโซลูชันที่ดีกว่าและช่วยให้มีนามธรรมที่ดีขึ้นในการจัดเก็บข้อมูล นอกจากนี้โมเดลของคุณไม่จำเป็นต้องเก็บไว้ในฐานข้อมูล สิ่งที่เกี่ยวกับการจัดเก็บเป็น XML หรือเข้าถึงโดยใช้บริการเว็บ? การเปลี่ยนกลไกการจัดเก็บโมเดลของคุณจะง่ายแค่ไหน?

ที่กล่าวว่า Active Record ไม่ได้แย่เสมอไปและเหมาะสำหรับแอปพลิเคชันที่เรียบง่ายกว่าซึ่งตัวเลือกอื่น ๆ จะมากเกินไป


1
เป็นเรื่องจริง แต่ขึ้นอยู่กับการใช้งานในระดับหนึ่ง
Mike Woodhouse

6

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

เพื่อตั้งชื่อ ...

มีรูปแบบที่ไม่สามารถใช้งานได้จริงเช่น:

  • Interpreter
  • Flyweight

นอกจากนี้ยังมีบางอย่างที่ยากที่จะเข้าใจเช่น:

  • Abstract Factory - รูปแบบโรงงานนามธรรมเต็มรูปแบบพร้อมกับครอบครัวของวัตถุที่สร้างขึ้นไม่ใช่เรื่องง่ายอย่างที่คิด
  • Bridge - อาจดูเป็นนามธรรมเกินไปหากมีการแบ่งส่วนนามธรรมและการนำไปใช้เป็นทรีย่อย แต่เป็นรูปแบบที่ใช้ได้มากในบางกรณี
  • Visitor - ความเข้าใจกลไกการจัดส่งสองครั้งเป็นสิ่งที่จำเป็นจริงๆ

และมีรูปแบบบางอย่างที่ดูเรียบง่ายมากแต่ไม่ใช่ตัวเลือกที่ชัดเจนนักเนื่องจากเหตุผลหลายประการที่เกี่ยวข้องกับหลักการหรือการนำไปใช้:

  • Singleton - ไม่ใช่รูปแบบที่แย่มากแค่ใช้มากเกินไป (บ่อยครั้งที่มันไม่เหมาะ)
  • Observer - รูปแบบที่ยอดเยี่ยม ... ทำให้โค้ดอ่านและแก้ไขข้อบกพร่องได้ยากขึ้น
  • Prototype - คอมไพเลอร์เทรดจะตรวจสอบความเคลื่อนไหว (ซึ่งอาจดีหรือไม่ดี ... ขึ้นอยู่กับ)
  • Chain of responsibility - บ่อยเกินไปเพียงแค่บังคับ / ผลักดันในการออกแบบ

สำหรับ "คนที่ไม่สามารถใช้งานได้จริง" ควรคิดให้ดีก่อนใช้เพราะมักจะมีวิธีแก้ปัญหาที่หรูหรากว่าที่ไหนสักแห่ง

สำหรับคนที่ "เข้าใจยากกว่า" ... พวกเขาเป็นตัวช่วยที่ดีมากเมื่อใช้ในสถานที่ที่เหมาะสมและเมื่อนำไปใช้งานได้ดี ... แต่พวกเขาจะฝันร้ายเมื่อใช้อย่างไม่เหมาะสม

เอาล่ะต่อไป ...


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

5

ฉันหวังว่าฉันจะไม่พ่ายแพ้มากเกินไปสำหรับเรื่องนี้ Christer Ericsson เขียนบทความที่สอง ( หนึ่ง , สอง ) ในเรื่องของรูปแบบการออกแบบของเขาในเวลาจริงบล็อกตรวจสอบการชน น้ำเสียงของเขาค่อนข้างรุนแรงและอาจจะเร้าใจไปหน่อย แต่ผู้ชายคนนั้นรู้เรื่องของเขาดังนั้นฉันจะไม่มองว่ามันเป็นความบ้าคลั่งของคนบ้า


การอ่านที่น่าสนใจ ขอบคุณสำหรับลิงค์!
Bombe

3
Morons สร้างรหัสที่ไม่ดี ปัญญาอ่อนที่มีรูปแบบสร้างรหัสที่แย่กว่าปัญญาอ่อนที่ไม่เคยเห็นรูปแบบหรือไม่? ฉันไม่คิดว่าพวกเขาทำ สำหรับคนฉลาดรูปแบบจะเป็นคำศัพท์ที่รู้จักกันดีซึ่งช่วยให้การแลกเปลี่ยนความคิดเห็นง่ายขึ้น วิธีแก้ปัญหา: เรียนรู้รูปแบบและจัดการกับโปรแกรมเมอร์ที่ชาญฉลาดเท่านั้น
Martin Brown

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

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

5

บางคนบอกว่าตัวระบุตำแหน่งบริการเป็นรูปแบบการต่อต้าน


สิ่งสำคัญที่ควรทราบคือในบางครั้งจำเป็นต้องมีตัวระบุตำแหน่งบริการ ตัวอย่างเช่นเมื่อคุณไม่มีการควบคุมอินสแตนซ์ของวัตถุอย่างเหมาะสม (เช่นแอตทริบิวต์ที่มีพารามิเตอร์ไม่คงที่ใน C #) แต่ก็เป็นไปได้ที่จะใช้ตัวระบุตำแหน่งบริการด้วยการฉีด ctor
Sinaesthetic

2

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


4
ฉันเข้าใจทุกอย่างในคำตอบของคุณจนถึงคำว่า "A"
1800 ข้อมูล

คุณอาจต้องขยายหรือเชื่อมโยงไปยังการวิเคราะห์การพึ่งพาอัตโนมัติที่คุณพูดถึงนี้ นอกจากนี้ในผู้รับมอบสิทธิ์ / เหตุการณ์. NET ยังใช้แทนรูปแบบผู้สังเกตการณ์
Spoike

3
@Spoike: ผู้แทน / กิจกรรมเป็นการดำเนินการตามรูปแบบผู้สังเกตการณ์
orip

1
ความไม่พอใจส่วนตัวของฉันต่อ Observer คือมันสามารถสร้างการรั่วไหลของหน่วยความจำในภาษาที่เก็บขยะได้ เมื่อคุณทำวัตถุเสร็จแล้วคุณต้องจำไว้ว่าวัตถุนั้นจะไม่ได้รับการทำความสะอาด
Martin Brown

@orip: ใช่นั่นคือเหตุผลที่คุณใช้ผู้รับมอบสิทธิ์ / เหตุการณ์ ;)
ปอยล์

2

ส่วนเสริมของโพสต์ของ Spoike การปรับโครงสร้างเป็นรูปแบบเป็นการอ่านที่ดี


ฉันได้เชื่อมโยงกับแคตตาล็อกของหนังสือบนอินเทอร์เน็ตแล้ว :)
ปอยล์

โอ้! ฉันไม่ได้รำคาญที่จะเลื่อนมัน จริงๆแล้วหลังจากจบคำถามหนังสือเล่มนี้ก็เข้ามาในความคิดของฉันแล้วฉันก็เห็นคำตอบของคุณ ฉันไม่สามารถหยุดตัวเองที่จะโพสต์ได้ :)
Adeel Ansari

0

Iterator เป็นรูปแบบ GoF อีกรูปแบบหนึ่งที่ควรหลีกเลี่ยงหรืออย่างน้อยก็ใช้เฉพาะเมื่อไม่มีทางเลือกอื่น

ทางเลือก ได้แก่ :

  1. สำหรับแต่ละวง โครงสร้างนี้มีอยู่ในภาษาหลักส่วนใหญ่และอาจใช้เพื่อหลีกเลี่ยงตัวทำซ้ำในกรณีส่วนใหญ่

  2. ตัวเลือกà la LINQ หรือ jQuery ควรใช้เมื่อสำหรับแต่ละรายการไม่เหมาะสมเนื่องจากไม่ควรประมวลผลวัตถุทั้งหมดจากคอนเทนเนอร์ ต่างจากตัวทำซ้ำตัวเลือกอนุญาตให้แสดงในที่เดียวว่าจะประมวลผลวัตถุชนิดใด


ฉันเห็นด้วยกับตัวเลือก Foreach เป็นตัววนซ้ำภาษา OO ส่วนใหญ่มีอินเทอร์เฟซที่สามารถทำซ้ำได้ซึ่งคุณใช้เพื่ออนุญาต foreach
Neil Aitken

ในบางภาษาสำหรับการสร้างแต่ละครั้งอาจดำเนินการผ่านตัวทำซ้ำ แต่แนวคิดของมันเป็นระดับสูงและใกล้เคียงกับตัวเลือกมากกว่า เมื่อใช้สำหรับนักพัฒนาแต่ละรายประกาศอย่างชัดเจนว่าควรประมวลผลองค์ประกอบทั้งหมดจากคอนเทนเนอร์
Volodymyr Frolov

ตัวทำซ้ำเป็นรูปแบบที่ยอดเยี่ยม การต่อต้านรูปแบบจะใช้ IEnumerable / IEnumerator โดยไม่มีตัววนซ้ำ ฉันเชื่อว่า LINQ เกิดขึ้นได้ผ่านตัวทำyieldซ้ำ เอริคสีขาวมีบางส่วนการอภิปรายที่ดีเกี่ยวกับเรื่องนี้ใน C # 3.0: blogs.msdn.com/b/ericwhite/archive/2006/10/04/... นอกจากนี้ตรวจสอบการอภิปรายเจเรมี Likness' บน coroutines กับ iterators: wintellect.com/CS/blogs/jlikness/archive/2010/03/23/...

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

Fwiw ทางเลือกไวยากรณ์ F # ที่เหมือน LINQ คือ "List.map (fun x -> x.Value) xs" ซึ่งยาวพอ ๆ กับความเข้าใจในรายการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.