วิธีการจัดรูปแบบที่อ่านง่ายที่สุดหากมีเงื่อนไข [ปิด]


43

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

if (FoobarBaz::quxQuux(corge, grault) || !garply(waldo) || fred(plugh) !== xyzzy) {
    thud();
}

หรือ

if (
    FoobarBaz::quxQuux(corge, grault)
 || !garply(waldo)
 || fred(plugh) !== xyzzy
) {
    thud();
}

หรือ

if (FoobarBaz::quxQuux(corge, grault)
    || !garply(waldo)
    || fred(plugh) !== xyzzy) {
    thud();
}

หรือ

thudable = FoobarBaz::quxQuux(corge, grault);
thudable ||= !garply(waldo);
thudable ||= fred(plugh) !== xyzzy;

if (thudable) {
    thud();
}

หรือการตั้งค่าอื่น ๆ

คำตอบ:


30

บ่อยครั้งที่เงื่อนไขยาวเป็นสัญญาณของรหัสที่ต้องการการปรับโครงสร้าง แต่บางครั้งคุณไม่สามารถหลีกเลี่ยงได้ ในกรณีเหล่านี้ฉันชอบครั้งแรก:

if (bar || baz || quux) { ... }

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

function foo() {
  return bar || baz || quux;
}

if (foo()) { ... }

3
เลื่อนไปด้านข้าง VS แนวตั้งไม่ได้เกือบข้อ จำกัด ก็คือในวันเก่าที่ไม่ดี ...
บิล

2
และให้ชื่อที่มีความหมาย (ธุรกิจ) แก่ฟังก์ชันเพื่อให้ผู้คนเข้าใจสิ่งที่ทดสอบที่นี่
Matthieu M.

19

ฉันต้องการให้ผู้ปฏิบัติงานสิ้นสุดเพื่อระบุความต่อเนื่อง:

if (the_function_being_called() != RETURNCODE_SUCCESS &&
    the_possibly_useful_recovery_strategy() == RETURNCODE_EPICFAIL &&
    this_user_has_elected_to_recieve_error_reports)
{
    report_error();
}

1
ฉันคิดว่าฉันชอบอันนี้ ฉันใช้วงเล็บจำนวนมากเพื่อให้แน่ใจว่าฉันสามารถเข้าใจลำดับความสำคัญได้เช่นกัน
Jasarien

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

11

ฉันเป็นแฟนตัวยงของชื่อตัวแปรที่สื่อความหมาย:

const bool isInAStrangeCondition =
    FoobarBaz::quxQuux(corge, grault) ||
    !garply(waldo) ||
    fred(plugh) !== xyzzy;

if (isInAStrangeCondition) {
    thud();
}

หรือ refactor เป็นฟังก์ชั่นดังกล่าวข้างต้น


7

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

bool goodblah = some_mess < whatever;
bool frobnacious = messy_crud != junky_expression;
bool yetanother = long_winded_condition;

if (goodblah || (frobnacious && yetanother))   {
    ...
}

นี่เป็นสิ่งที่ดีโดยเฉพาะในตัวดีบักเกอร์ซึ่งฉันสามารถดูบูลทั้งหมดก่อนที่จะเรียกใช้งาน 'if'


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

... และคุณจะต้องเก่งในการตั้งชื่อตัวแปรมากมายตลอดทั้งวัน ...
cronvel

6

ฉันมักจะจัดตำแหน่งโอเปอเรเตอร์ที่จุดเริ่มต้นของบรรทัดใหม่ดังนั้นฉันจึงจำได้ว่าฉันรวมคำต่างๆอย่างไร (ทั้งสำหรับตรรกะยาวและคณิตศาสตร์ยาว) แบบนี้:

if (first_attempt(data) == SUCCESS
    || (reusable(data) && second_attempt(data) == SUCCESS)
    || (still_reusable(data) && third_attempt(data) == SUCCESS))
  return SUCCESS;

ใช้งานได้เฉพาะถ้าฉันเยื้องด้วยช่องว่าง 2 ชุดหรือตั้งค่าสภาพแวดล้อมของฉันเพื่อเยื้อง multiline เพรดิเคตมากขึ้นมิฉะนั้นจะเป็นการยากที่จะบอกว่าจุดสิ้นสุดสิ้นสุดแล้ว


0

ฉันเป็นแฟนของต่อไปนี้:

if (really_long_expression && another_really_really_long_expression && 
            another_very_long_expression_OMG_id_it_long){
    bugs();
}

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

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


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