มันจะดีกว่าที่จะป้องกันวิธีการโทรหรือวิธีการเอง?


12

ฉันกำลังเขียนใบสมัครและฉันมาถึงจุดนี้:

private void SomeMethod()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }

    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

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

private void SomeMethod()
{
    GiveApples();
    GiveBananas();
}

private void GiveApples()
{
    if (!Settings.GiveApples)
    {
        return;
    }

    ...
}

private void GiveBananas()
{
    if (!Settings.GiveBananas)
    {
        return;
    }

    ...
}

ในกรณีที่สองแต่ละวิธีจะป้องกันตัวเองดังนั้นแม้ว่าจะมีวิธีใดวิธีหนึ่งGiveApplesหรือGiveBananasถูกเรียกจากภายนอกSomeMethodพวกเขาจะถูกเรียกใช้งานก็ต่อเมื่อมีการตั้งค่าสถานะที่ถูกต้องในการตั้งค่า

นี่เป็นสิ่งที่ฉันควรพิจารณาว่าเป็นปัญหาหรือไม่

ในบริบทปัจจุบันของฉันเป็นไปได้ยากมากที่จะเรียกวิธีการทั้งสองจากภายนอกวิธีนี้ แต่ไม่มีใครสามารถรับประกันได้ว่า


5
ขึ้นอยู่กับว่าคุณอาจต้องโทรหา GiveApples หรือ GiveBananas โดยไม่ตรวจสอบก่อน เนื่องจากตัวป้องกันถูกเชื่อมโยงกับวิธีการจึงอาจเป็นของวิธีการ
Robert Harvey

คำตอบ:


13

ฉันคิดว่าทหารเป็นวิธีที่ต้องปฏิบัติตาม ในตัวอย่างของคุณเมธอดต้องไม่ระบุแอปเปิ้ลหาก Settings.GiveApples เป็นเท็จ

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

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


5

วางยามภายในวิธีการของตัวเอง ผู้บริโภคของGiveApples()หรือไม่ควรจะรับผิดชอบในการจัดการยามของ GiveBananas()GiveApples()

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

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


4

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

private void SomeMethod()
{
    GiveApplesIfActivated();
    GiveBananasIfActivated();
}

private void GiveApplesIfActivated()
{
    if (Settings.GiveApples)
    {
        GiveApples();
    }
}

private void GiveBananasIfActivated()
{
    if (Settings.GiveBananas)
    {
        GiveBananas();
    }
}

private void GiveApples()
{
    ...
}

private void GiveBananas()
{
    ...
}

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

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

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