รูปแบบตัววนซ้ำ - ทำไมจึงเป็นเรื่องสำคัญที่จะไม่เปิดเผยการเป็นตัวแทนภายใน


24

ฉันอ่านC # ออกแบบ Essentials ฉันกำลังอ่านเกี่ยวกับรูปแบบตัววนซ้ำ

ฉันเข้าใจวิธีการนำไปใช้อย่างสมบูรณ์ แต่ฉันไม่เข้าใจความสำคัญหรือดูกรณีการใช้งาน ในหนังสือจะมีตัวอย่างให้ในกรณีที่มีคนต้องการได้รับรายชื่อของวัตถุ พวกเขาจะได้ทำเช่นนี้โดยการเปิดเผยทรัพย์สินของประชาชนเช่นหรือIList<T>Array

หนังสือเล่มนี้เขียน

ปัญหาเกี่ยวกับเรื่องนี้คือการเป็นตัวแทนภายในในทั้งสองชั้นเรียนเหล่านี้ได้สัมผัสกับโครงการภายนอก

การเป็นตัวแทนภายในคืออะไร? ความจริงมันเป็นarrayหรือIList<T>? ฉันไม่เข้าใจจริงๆว่าทำไมสิ่งนี้เป็นสิ่งที่ไม่ดีสำหรับผู้บริโภค (โปรแกรมเมอร์ที่เรียกสิ่งนี้) รู้ ...

หนังสือบอกว่ารูปแบบนี้ใช้งานได้โดยเปิดเผยGetEnumeratorฟังก์ชั่นของมันเพื่อให้เราสามารถเรียกGetEnumerator()และเปิดเผย 'รายการ' ด้วยวิธีนี้

ฉันคิดว่ารูปแบบนี้มีสถานที่ (เหมือนทั้งหมด) ในบางสถานการณ์ แต่ฉันไม่เห็นว่าที่ไหนและเมื่อไหร่


1
อ่านเพิ่มเติม: en.m.wikipedia.org/wiki/Law_of_Demeter
Jules

4
เนื่องจากการนำไปปฏิบัติอาจต้องการเปลี่ยนจากการใช้อาเรย์เป็นการใช้ลิสต์ที่เชื่อมโยงโดยไม่ต้องเปลี่ยนแปลงคลาสผู้บริโภค สิ่งนี้จะเป็นไปไม่ได้ถ้าผู้บริโภครู้ว่าได้คืนคลาสที่แน่นอน
MTilsted

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

สมมติว่าเรามีความสุข "อินเตอร์เฟซ" Fที่ทำให้ผมมีความรู้ (วิธีการ) ของa, และb cทุกอย่างดีและดีอาจมีหลายสิ่งที่แตกต่างกัน แต่เพียงFเพื่อฉัน คิดว่าวิธีการนั้นเป็น "ข้อ จำกัด " หรือข้อสัญญาที่Fผูกมัดให้ชั้นเรียนทำ สมมติว่าเราเพิ่มส่วนหนึ่งdเพราะเราต้องการ นี้จะเพิ่มข้อ จำกัด เพิ่มเติมทุกครั้งที่เราทำเช่นนี้เรากำหนดขึ้นและมากขึ้นในFs ในที่สุด (กรณีที่เลวร้ายที่สุด) มีเพียงสิ่งเดียวเท่านั้นที่สามารถเป็นได้Fดังนั้นเราจึงอาจไม่มีมัน และFข้อ จำกัด มากมายมีเพียงวิธีเดียวที่จะทำได้
Alec Teal

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

คำตอบ:


56

ซอฟต์แวร์เป็นเกมแห่งสัญญาและสิทธิพิเศษ มันเป็นความคิดที่ดีที่จะสัญญามากกว่าที่คุณจะสามารถส่งมอบหรือมากกว่าความร่วมมือของคุณ

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

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

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


12
Exposing the concrete type Array usually creates many additional promises, e.g. that you can sort the collection by a function of your own choosing...- ยอดเยี่ยม ฉันแค่คิดไม่ออก ใช่มันนำ 'การทำซ้ำ' กลับมาและทำซ้ำเท่านั้น!
MyDaftQuestions

18

การซ่อนการนำไปปฏิบัตินั้นเป็นหลักการสำคัญของ OOP และเป็นแนวคิดที่ดีในกระบวนทัศน์ทั้งหมด แต่มันมีความสำคัญอย่างยิ่งสำหรับผู้ทำซ้ำ (หรือสิ่งที่พวกเขาเรียกว่าในภาษาเฉพาะนั้น) ในภาษาที่สนับสนุนการทำซ้ำที่ขี้เกียจ

ปัญหาเกี่ยวกับการเปิดเผยชนิดที่เป็นรูปธรรมของ iterables - หรือแม้กระทั่งอินเตอร์เฟสเหมือนIList<T>- ไม่ได้อยู่ในวัตถุที่เปิดเผยพวกเขา แต่ในวิธีการที่ใช้พวกเขา ตัวอย่างเช่นสมมติว่าคุณมีฟังก์ชั่นสำหรับการพิมพ์รายการFoos:

void PrintFoos(IList<Foo> foos)
{
    foreach (foo in foos)
    {
        Console.WriteLine(foo);
    }
}

คุณสามารถใช้ฟังก์ชั่นนั้นเพื่อพิมพ์รายการของ foo เท่านั้น IList<Foo>

IList<Foo> foos = //.....
PrintFoos(foos);

แต่ถ้าคุณต้องการพิมพ์รายการที่จัดทำดัชนีทุกรายการ? คุณจะต้องสร้างรายการใหม่:

IList<Foo> everySecondFoo = new List<T>();
bool isIndexEven = true;
foreach (foo; foos)
{
    if (isIndexEven)
    {
        everySecondFoo.Add(foo);
    }
    isIndexEven = !isIndexEven;
}
PrintFoos(everySecondFoo);

นี่ค่อนข้างนาน แต่ด้วย LINQ เราสามารถทำมันให้เป็นซับเดียวซึ่งจริงๆแล้วสามารถอ่านได้มากขึ้น:

PrintFoos(foos.Where((foo, i) => i % 2 == 0).ToList());

ตอนนี้คุณสังเกตเห็น.ToList()สิ่งสุดท้ายแล้วหรือยัง? สิ่งนี้จะแปลงแบบสอบถามแบบสันหลังยาวเป็นรายการเพื่อให้เราสามารถส่งต่อไปPrintFoosได้ สิ่งนี้ต้องการการจัดสรรรายการที่สองและสองรายการผ่าน (รายการหนึ่งในรายการแรกเพื่อสร้างรายการที่สองและอีกรายการในรายการที่สองเพื่อพิมพ์) นอกจากนี้ถ้าเรามีสิ่งนี้:

void Print6Foos(IList<Foo> foos)
{
    int counter = 0;
    foreach (foo in foos)
    {
        Console.WriteLine(foo);
        ++ counter;
        if (6 < counter)
        {
            return;
        }
    }
}

// ........

Print6Foos(foos.Where((foo, i) => i % 2 == 0).ToList());

เกิดอะไรขึ้นถ้าfoosมีหลายพันรายการ? เราจะต้องผ่านพวกเขาทั้งหมดและจัดสรรรายการใหญ่เพื่อพิมพ์ 6 รายการ!

ป้อน Enumerators - รูปแบบ Iterator รุ่น C # แทนที่จะให้ฟังก์ชั่นของเรายอมรับรายการเราทำให้มันเป็นที่ยอมรับEnumerable:

void Print6Foos(Enumerable<Foo> foos)
{
    // everything else stays the same
}

// ........

Print6Foos(foos.Where((foo, i) => i % 2 == 0));

ตอนนี้Print6Foosสามารถทำซ้ำอย่างเกียจคร้านใน 6 รายการแรกของรายการและเราไม่จำเป็นต้องสัมผัสส่วนที่เหลือของมัน

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


6

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

ไม่ว่าด้วยเหตุผลใดก็ตามคุณกำลังตัดสินใจเปลี่ยนการเป็นตัวแทนภายในเป็นIAmWhatever<T>ในเวลาต่อมา แทนที่จะเพียงแค่เปลี่ยน internals ของคลาสคุณจะต้องเปลี่ยนทุกบรรทัดของ code และ method โดยอาศัยการแทนค่าชนิดของ internalIList<T>บรรทัดของรหัสและวิธีการในการพึ่งพาการแสดงภายในเป็นประเภทนี่เป็นเรื่องที่ยุ่งยากและมีแนวโน้มที่จะเกิดข้อผิดพลาดได้ดีที่สุดเมื่อคุณเป็นคนเดียวที่ใช้คลาส แต่อาจทำลายรหัสประชาชนอื่น ๆ ที่ใช้คลาสของคุณ หากคุณเพิ่งเปิดเผยวิธีการสาธารณะโดยไม่เปิดเผย internals ใด ๆ คุณสามารถเปลี่ยนการแสดงภายในโดยไม่ต้องมีบรรทัดของรหัสใด ๆ นอกชั้นเรียนของคุณสังเกตเห็นการทำงานเหมือนไม่มีอะไรเปลี่ยนแปลง

นี่คือเหตุผลที่ encapsulation เป็นหนึ่งในส่วนที่สำคัญที่สุดของการออกแบบซอฟแวร์ที่ไม่สำคัญ


6

ยิ่งคุณพูดน้อยเท่าไหร่คุณก็ยิ่งพูดน้อยลง

ยิ่งคุณถามน้อยเท่าไหร่คุณก็จะยิ่งถูกบอกน้อย

หากรหัสของคุณเพียง exposes IEnumerable<T>ซึ่งสนับสนุนเฉพาะGetEnumrator()มันจะถูกแทนที่ด้วยรหัสอื่น ๆ IEnumerable<T>ที่สามารถขอรับการสนับสนุน สิ่งนี้เพิ่มความยืดหยุ่น

หากรหัสของคุณใช้เพียงรหัสIEnumerable<T>นั้นสามารถรองรับรหัสใด ๆ ที่ใช้งานIEnumerable<T>ได้ อีกครั้งมีความยืดหยุ่นเป็นพิเศษ

ทั้งหมดของ LINQ IEnumerable<T>เพื่อวัตถุตัวอย่างเช่นขึ้นอยู่กับ ในขณะที่มันรวดเร็วในการใช้งานบางอย่างของIEnumerable<T>มันทำสิ่งนี้ในวิธีการทดสอบและการใช้งานที่สามารถย้อนกลับไปใช้เพียงแค่GetEnumerator()และการIEnumerator<T>ใช้งานที่กลับมา สิ่งนี้ให้ความยืดหยุ่นมากกว่าการสร้างบนอาร์เรย์หรือรายการ


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

0

ถ้อยคำที่ฉันชอบจะใช้ความคิดเห็นของ @CaptainMan Mirror: "เป็นการดีที่ผู้บริโภคจะรู้รายละเอียดภายในมันไม่ดีสำหรับลูกค้าที่จะต้องรู้รายละเอียดภายใน"

หากลูกค้าต้องพิมพ์arrayหรือIList<T>รหัสของพวกเขาเมื่อประเภทเหล่านั้นมีรายละเอียดภายในผู้บริโภคจะต้องทำให้ถูกต้อง หากพวกเขาผิดผู้บริโภคอาจไม่รวบรวมหรือแม้แต่ได้รับผลลัพธ์ที่ผิด สิ่งนี้ให้พฤติกรรมเช่นเดียวกับคำตอบอื่น ๆ ของ "ซ่อนรายละเอียดการใช้งานเสมอเพราะคุณไม่ควรเปิดเผย" แต่เริ่มขุดที่ข้อดีของการไม่เปิดเผย หากคุณไม่เคยเปิดเผยรายละเอียดการใช้งานลูกค้าของคุณจะไม่ผูกมัดด้วยการใช้มัน!

ฉันชอบที่จะคิดในแง่นี้เพราะมันเปิดแนวคิดของการซ่อนการใช้งานกับเฉดสีของความหมายมากกว่า draconian "ซ่อนรายละเอียดการใช้งานของคุณเสมอ" มีสถานการณ์มากมายที่การเปิดเผยการนำไปใช้นั้นถูกต้องสมบูรณ์ พิจารณากรณีของไดรเวอร์อุปกรณ์แบบเรียลไทม์ที่ความสามารถในการข้ามเลเยอร์ที่ผ่านมาของ abstraction และ poke bytes ลงในตำแหน่งที่ถูกต้องอาจเป็นความแตกต่างระหว่างการกำหนดเวลาหรือไม่ หรือพิจารณาสภาพแวดล้อมการพัฒนาที่คุณไม่มีเวลาสร้าง "API ที่ดี" และต้องใช้สิ่งต่าง ๆ ทันที บ่อยครั้งที่การเปิดเผย API พื้นฐานในสภาพแวดล้อมดังกล่าวอาจเป็นความแตกต่างระหว่างการกำหนดเวลาหรือไม่

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

กรณีศึกษาที่ฉันเห็นครั้งแล้วครั้งเล่าเป็นกรณีที่ผู้พัฒนาสร้าง API ที่ไม่ได้ระมัดระวังในการซ่อนรายละเอียดการใช้งาน ผู้พัฒนารายที่สองซึ่งใช้ไลบรารีนั้นพบว่า API ขาดคุณลักษณะสำคัญบางอย่างที่พวกเขาต้องการ แทนที่จะเขียนคำขอคุณลักษณะ (ซึ่งอาจมีเวลาตอบสนองเดือน) พวกเขาตัดสินใจที่จะละเมิดการเข้าถึงรายละเอียดการใช้งานที่ซ่อนอยู่ (ซึ่งใช้เวลาไม่กี่วินาที) สิ่งนี้ไม่เลวในตัวมันเอง แต่บ่อยครั้งที่นักพัฒนา API ไม่เคยวางแผนว่าจะเป็นส่วนหนึ่งของ API ต่อมาเมื่อพวกเขาปรับปรุง API และเปลี่ยนแปลงรายละเอียดพื้นฐานพวกเขาพบว่าพวกเขาถูกผูกมัดกับการใช้งานเก่าเพราะมีคนใช้มันเป็นส่วนหนึ่งของ API เวอร์ชันที่เลวร้ายที่สุดคือที่มีคนใช้ API ของคุณเพื่อมอบคุณลักษณะที่ยึดลูกค้าเป็นศูนย์กลางและตอนนี้ บริษัท ของคุณ ' s paycheck เชื่อมโยงกับ API ที่มีข้อบกพร่อง! เพียงแค่เปิดเผยรายละเอียดการนำไปปฏิบัติเมื่อคุณไม่รู้ว่าลูกค้าของคุณพิสูจน์แล้วว่าเพียงพอที่จะผูกบ่วงรอบ API ของคุณ!


1
Re: "หรือพิจารณาสภาพแวดล้อมการพัฒนาที่คุณไม่มีเวลาในการสร้าง 'API ที่ดี' และต้องใช้สิ่งต่าง ๆ ในทันที": หากคุณพบว่าตัวเองอยู่ในสภาพแวดล้อมดังกล่าวและด้วยเหตุผลบางอย่างไม่ต้องการเลิก ( หรือไม่แน่ใจว่าถ้าคุณทำ) ผมขอแนะนำหนังสือเล่มนี้ตายมีนาคม: คู่มือสำหรับนักพัฒนาซอฟแวร์ที่สมบูรณ์แบบที่จะรอดตาย 'Mission Impossible' โครงการ มันมีคำแนะนำที่ดีเยี่ยมในเรื่อง (นอกจากนี้ฉันขอแนะนำให้เปลี่ยนความคิดของคุณเกี่ยวกับการไม่เลิก)
ruakh

@ruakh ฉันพบว่ามันสำคัญเสมอที่จะเข้าใจวิธีการทำงานในสภาพแวดล้อมที่คุณไม่มีเวลาทำ API ที่ดี ตรงไปตรงมากที่สุดเท่าที่เรารักวิธีหอคอยงาช้างรหัสจริงคือสิ่งที่จ่ายค่า ยิ่งเรายอมรับได้เร็วเท่าไหร่เราก็ยิ่งเริ่มเข้าถึงซอฟต์แวร์ได้เร็วขึ้นโดยจะเป็นการสร้างสมดุลระหว่างคุณภาพ API กับโค้ดที่มีประสิทธิผลเพื่อให้เข้ากับสภาพแวดล้อมที่แน่นอนของเรา ฉันเคยเห็นผู้พัฒนารุ่นเยาว์จำนวนมากเกินไปติดกับดักของอุดมคติไม่ได้ตระหนักว่าพวกเขาต้องดิ้นรน (ฉันยังเป็นนักพัฒนาหนุ่มคนนั้น .. ยังคงฟื้นตัวจากการออกแบบ "API ที่ดี" 5 ปี)
Cort Ammon - Reinstate Monica

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

1
@ruakh สิ่งที่ฉันได้พบคือมันเป็นไปได้ที่จะสร้างโค้ดที่ดีโดยไม่มี "API ที่ดี" หากได้รับโอกาส API ที่ดีนั้นดี แต่การปฏิบัติต่อพวกเขาในกรณีที่มีความจำเป็นจะทำให้เกิดความขัดแย้งมากกว่าที่ควรค่า ลองพิจารณา: API สำหรับร่างกายมนุษย์นั้นน่ากลัว แต่เราก็ยังคิดว่าพวกมันค่อนข้างดีทางด้านวิศวกรรม =)
Cort Ammon - Reinstate Monica

อีกตัวอย่างหนึ่งที่ฉันให้คือแรงบันดาลใจในการถกเถียงเรื่องเวลา กลุ่มหนึ่งที่ฉันทำงานด้วยมีโปรแกรมควบคุมอุปกรณ์บางอย่างที่พวกเขาต้องการในการพัฒนาพร้อมกับข้อกำหนดแบบเรียลไทม์ พวกเขามี 2 API ที่จะทำงานด้วย หนึ่งดี แต่น้อยกว่า API ที่ดีไม่สามารถกำหนดเวลาได้เพราะซ่อนการใช้งานไว้ API ที่น้อยกว่าเปิดเผยการใช้งานและในการทำเช่นนั้นให้คุณใช้เทคนิคเฉพาะโปรเซสเซอร์เพื่อสร้างผลิตภัณฑ์ที่ใช้งานได้ API ที่ดีนั้นวางอยู่บนชั้นวางอย่างสุภาพและพวกเขายังคงปฏิบัติตามข้อกำหนดด้านเวลา
Cort Ammon - Reinstate Monica

0

คุณไม่จำเป็นต้องทราบว่าข้อมูลภายในของคุณคืออะไรหรืออาจเกิดขึ้นในอนาคต

สมมติว่าคุณมีแหล่งข้อมูลที่คุณเป็นตัวแทนของอาร์เรย์คุณอาจวนซ้ำกับแหล่งข้อมูลปกติ

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

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

หากคุณมี 1,000 คลาสที่พยายามเข้าถึงวัตถุข้อมูลตอนนี้คุณมีปัญหาในการเปลี่ยนโครงสร้างครั้งใหญ่

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

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