การตรวจสอบความถูกต้องของพารามิเตอร์อินพุตในตัวเรียก: การทำสำเนารหัสหรือไม่


16

สถานที่ที่ดีที่สุดในการตรวจสอบความถูกต้องของพารามิเตอร์อินพุตของฟังก์ชัน: ในผู้โทรเข้าหรือในฟังก์ชั่นของตัวเอง?

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

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

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

ฉันไม่ได้สนใจเพียงแค่ในเงื่อนไขที่เป็นโมฆะ แต่ในการตรวจสอบตัวแปรอินพุตใด ๆ (ค่าลบเพื่อsqrtฟังก์ชั่นหารด้วยศูนย์การรวมรัฐและรหัสไปรษณีย์ผิดหรืออย่างอื่น)

มีกฎบางอย่างในการตัดสินใจว่าจะตรวจสอบสภาพอินพุตอย่างไร

ฉันกำลังคิดถึงข้อโต้แย้งบางอย่าง:

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

ฉันหวังว่าคำถามนี้จะไม่ซ้ำกันฉันค้นหาปัญหานี้และฉันพบคำถามที่คล้ายกัน แต่พวกเขาไม่ได้พูดถึงกรณีนี้อย่างแน่นอน

คำตอบ:


15

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

นี่เป็นแนวคิดที่สำคัญอย่างยิ่งเมื่อคุณสร้างวิธีการสาธารณะเพราะโดยทั่วไปคุณโฆษณาว่าวิธีการบางอย่างดำเนินการบางอย่าง ทำสิ่งที่คุณพูดได้ดีขึ้น!

ใช้วิธีการต่อไปนี้เป็นตัวอย่าง:

public void DeletePerson(Person p)
{            
    _database.Delete(p);
}

สัญญาโดยนัยDeletePersonคืออะไร? โปรแกรมเมอร์สามารถสันนิษฐานได้ว่าหากPersonมีการส่งผ่านมันจะถูกลบ อย่างไรก็ตามเรารู้ว่านี่ไม่เป็นความจริงเสมอไป เกิดอะไรขึ้นถ้าpเป็นnullค่า? เกิดอะไรขึ้นถ้าpไม่มีอยู่ในฐานข้อมูล เกิดอะไรขึ้นถ้าฐานข้อมูลถูกตัดการเชื่อมต่อ? ดังนั้นDeletePerson จึงไม่สามารถทำตามสัญญาให้สำเร็จได้ บางครั้งจะลบบุคคลและบางครั้งก็ส่ง NullReferenceException หรือ DatabaseNotConnectedException หรือบางครั้งก็ไม่ทำอะไรเลย (เช่นถ้าบุคคลนั้นถูกลบไปแล้ว)

APIs เช่นนี้มีชื่อเสียงที่ใช้งานยากเพราะเมื่อคุณเรียกวิธีนี้ว่า "กล่องดำ" วิธีการทุกอย่างจะเกิดขึ้นได้

นี่คือสองวิธีที่คุณสามารถปรับปรุงสัญญา:

  • เพิ่มการตรวจสอบและเพิ่มข้อยกเว้นให้กับสัญญา สิ่งนี้ทำให้สัญญาแข็งแกร่งขึ้นแต่ต้องการให้ผู้เรียกทำการตรวจสอบความถูกต้อง อย่างไรก็ตามความแตกต่างคือตอนนี้พวกเขารู้ถึงข้อกำหนดของพวกเขาแล้ว ในกรณีนี้ฉันสื่อสารสิ่งนี้ด้วยความคิดเห็น C # XML แต่คุณสามารถเพิ่มthrows(Java) ใช้Assertหรือใช้เครื่องมือสัญญาเช่นสัญญารหัส

    ///<exception>ArgumentNullException</exception>
    ///<exception>ArgumentException</exception>
    public void DeletePerson(Person p)
    {            
        if(p == null)
            throw new ArgumentNullException("p");
        if(!_database.Contains(p))
            throw new ArgumentException("The Person specified is not in the database.");
    
        _database.Delete(p);
    }
    

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

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

    public void TryDeletePerson(Person p)
    {            
        if(p == null || !_database.Contains(p))
            return;
    
        _database.Delete(p);
    }
    
  • รวมวิธีการ บางครั้งคุณต้องการทั้งคู่เล็กน้อยที่คุณต้องการให้ผู้โทรภายนอกปฏิบัติตามกฎอย่างใกล้ชิด (เพื่อบังคับให้พวกเขาต้องรับผิดชอบรหัส) แต่คุณต้องการให้รหัสส่วนตัวของคุณยืดหยุ่นได้

    ///<exception>ArgumentNullException</exception>
    ///<exception>ArgumentException</exception>
    public void DeletePerson(Person p)
    {            
        if(p == null)
            throw new ArgumentNullException("p");
        if(!_database.Contains(p))
            throw new ArgumentException("The Person specified is not in the database.");
    
        TryDeletePerson(p);
    }
    
    internal void TryDeletePerson(Person p)
    {            
        if(p == null || !_database.Contains(p))
            return;
    
        _database.Delete(p);
    }
    

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


ขอบคุณสำหรับคำตอบที่ดีมากพร้อมตัวอย่าง ฉันชอบประเด็น "การป้องกัน" และ "สัญญาที่เข้มงวด"
srnka

7

มันเป็นเรื่องของการประชุมเอกสารและการใช้กรณี

ฟังก์ชันทั้งหมดไม่เท่ากัน ข้อกำหนดทั้งหมดไม่เท่ากัน การตรวจสอบความถูกต้องไม่เท่ากันทั้งหมด

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

เกิดอะไรขึ้นถ้าโครงการอยู่ใน C ++? ข้อตกลง / ประเพณีใน C ++ คือเอกสารเงื่อนไขเบื้องต้น แต่เพียงตรวจสอบพวกเขา (ถ้าเลย) ใน debug builds

ไม่ว่าในกรณีใดคุณมีเงื่อนไขที่กำหนดไว้ล่วงหน้าในฟังก์ชั่นของคุณ: ไม่มีอาร์กิวเมนต์ใดที่อาจเป็นโมฆะ คุณสามารถขยายโดเมนของฟังก์ชันเพื่อรวมค่า null ด้วยพฤติกรรมที่กำหนดไว้เช่น "ถ้าอาร์กิวเมนต์ใด ๆ เป็นโมฆะจะมีข้อยกเว้น" แน่นอนว่ามรดกทางวัฒนธรรม C ++ ของฉันพูดที่นี่อีกครั้ง - ใน Java มันเป็นเรื่องธรรมดาพอที่จะบันทึกเอกสารด้วยวิธีนี้

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

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


ขอบคุณสำหรับคำตอบ. คุณได้โปรดให้ลิงก์กับคำแนะนำสไตล์ Guava หรือไม่ ฉันไม่สามารถ google และค้นหาสิ่งที่คุณหมายถึงมัน +1 สำหรับการตรวจสอบขอบเขต
srnka

เพิ่มลิงค์ จริงๆแล้วมันไม่ได้เป็นคู่มือแบบเต็มเพียงส่วนหนึ่งของเอกสารของสาธารณูปโภคที่ไม่ใช่โมฆะ
Sebastian Redl

6

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

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


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

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

4

ภายในฟังก์ชั่นนั้นเอง หากมีการใช้งานฟังก์ชันมากกว่าหนึ่งครั้งคุณจะไม่ต้องการตรวจสอบพารามิเตอร์สำหรับการเรียกใช้ฟังก์ชันทุกครั้ง

นอกจากนี้หากฟังก์ชั่นได้รับการปรับปรุงในลักษณะที่จะส่งผลกระทบต่อการตรวจสอบความถูกต้องของพารามิเตอร์คุณจะต้องค้นหาการตรวจสอบความถูกต้องของผู้โทรทุกครั้งเพื่ออัพเดท มันไม่น่ารัก :-)

คุณอาจอ้างถึงGuard Clause

ปรับปรุง

ดูคำตอบของฉันสำหรับแต่ละสถานการณ์ที่คุณระบุ

  • เมื่อการรักษาของตัวแปรที่ไม่ถูกต้องอาจแตกต่างกันเป็นสิ่งที่ดีในการตรวจสอบในด้านของผู้โทร (เช่นsqrt()ฟังก์ชั่น - ในบางกรณีฉันอาจต้องการที่จะทำงานกับจำนวนที่ซับซ้อนดังนั้นฉันปฏิบัติต่อเงื่อนไขในการโทร)

    ตอบ

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

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

    หากคุณต้องการคุณสามารถห่อมันรอบsqrtฟังก์ชั่นที่กำหนดเองของคุณที่จัดการกับจำนวนลบและส่งกลับจำนวนที่ซับซ้อน

  • เมื่อเงื่อนไขการตรวจสอบเหมือนกันในผู้โทรทุกคนควรตรวจสอบภายในฟังก์ชั่นเพื่อหลีกเลี่ยงการซ้ำซ้อน

    ตอบ

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

  • การตรวจสอบความถูกต้องของพารามิเตอร์อินพุตในตัวเรียกเกิดขึ้นเพียงครั้งเดียวก่อนที่จะเรียกใช้ฟังก์ชันจำนวนมากด้วยพารามิเตอร์นี้ ดังนั้นการตรวจสอบความถูกต้องของพารามิเตอร์ในแต่ละฟังก์ชั่นจึงไม่มีประสิทธิภาพ

    ตอบ

    มันจะดีถ้าผู้เรียกเป็นฟังก์ชั่นคุณไม่คิดเหรอ?

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

  • วิธีการแก้ปัญหาที่เหมาะสมขึ้นอยู่กับกรณีเฉพาะ

    ตอบ

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


ขอบคุณสำหรับคำตอบ. sqrt () เป็นเพียงตัวอย่างพฤติกรรมเดียวกับพารามิเตอร์อินพุตสามารถใช้โดยฟังก์ชั่นอื่น ๆ มากมาย "หากฟังก์ชั่นได้รับการปรับปรุงในลักษณะที่จะส่งผลต่อการตรวจสอบความถูกต้องของพารามิเตอร์คุณต้องค้นหาการตรวจสอบความถูกต้องของผู้โทรทุกครั้ง" - ฉันไม่เห็นด้วยกับสิ่งนี้ จากนั้นเราสามารถพูดเหมือนกันสำหรับค่าส่งคืน: หากฟังก์ชั่นมีการปรับปรุงในลักษณะที่จะส่งผลกระทบต่อมูลค่าที่ส่งคืนคุณต้องแก้ไขผู้โทรทุกคน ... ฉันคิดว่าฟังก์ชั่นต้องมีงานที่กำหนดไว้อย่างดี ... จำเป็นต้องเปลี่ยนผู้โทร
srnka

2

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

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

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

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


+1 ขอบคุณสำหรับคำตอบ การสะท้อนที่ดี: "การตรวจสอบความถูกต้องส่งผลให้เกิดการทำสำเนารหัสและทำงานที่ไม่จำเป็นจำนวนมาก" และในประโยค: "ในกรณีส่วนใหญ่ไม่จำเป็นต้องทำการทดสอบที่ชัดเจนเนื่องจากตรรกะภายในและเงื่อนไขล่วงหน้าของผู้โทรมาทำให้แน่ใจแล้ว" - คุณหมายถึงอะไรกับการแสดงออกของ "ตรรกะภายใน"? ฟังก์ชั่น DBC?
srnka

@srnka: ด้วย "ตรรกะภายใน" ฉันหมายถึงการคำนวณและการตัดสินใจในฟังก์ชั่น มันคือการใช้งานของฟังก์ชั่นเป็นหลัก
Bart van Ingen Schenau

0

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

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


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