ใช้การเขียนโปรแกรมที่ไม่ดีของ ELSE หรือไม่ [ปิด]


18

ฉันมักจะเจอข้อบกพร่องที่เกิดจากการใช้ELSEโครงสร้าง ตัวอย่างที่สำคัญคือบางสิ่งบางอย่างตามแนวของ:

If (passwordCheck() == false){
    displayMessage();
}else{
    letThemIn();
}

สำหรับฉันแล้วปัญหาด้านความปลอดภัยนี้ส่งเสียงร้อง ฉันรู้ว่า passwordCheck มีแนวโน้มที่จะเป็นบูลีน แต่ฉันจะไม่วางความปลอดภัยของแอปพลิเคชันของฉันไว้ในนั้น จะเกิดอะไรขึ้นถ้ามันเป็นสตริง, int เป็นต้น?

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

แน่นอนว่านี่เป็นวิธีที่ดีกว่าในการป้องกันข้อผิดพลาด / ปัญหาด้านความปลอดภัยในแอปของคุณ

พวกคุณทำยังไง?


3
ปัญหาด้านความปลอดภัยสำหรับคุณคืออะไร "passwordCheck" หมายถึงอะไร มีการตรวจสอบรหัสผ่านหรือไม่ จะต้องมีการตรวจสอบรหัสผ่านหรือไม่? ผู้ใช้ได้ผ่านไปแล้ว? ผู้ใช้ป้อนรหัสผ่านไม่ถูกต้อง?
LennyProgrammers

20
I know that passwordCheck is likely to be a boolean...คุณหมายถึงอะไร ในทุก ๆ ภาษาที่แข็งแรง passwordCheckจะเป็นอะไรก็ได้ที่คุณต้องการ
Bobby

31
ผมคิดว่าการปฏิบัติที่ไม่ดีเยื้องนำไปสู่ข้อผิดพลาดมากกว่าการใช้elseงบ ...
gablin

15
ดูเหมือนว่าจะแปลก ครั้งแรกที่คุณบ่นเกี่ยวกับชนิดกลับเป็นไปได้ของpasswordCheck()อาจจะไม่เป็นแบบบูล (ซึ่งอาจจะเป็นความกังวลที่เหมาะสม) และจากนั้นคุณตำหนิบนelse? ฉันไม่เห็นสิ่งที่เป็นelseสาเหตุของปัญหา
David Thornley

8
mmm ผมคิดว่าถามว่าใช้อื่นใดคือการเขียนโปรแกรมที่ดีคือการเขียนโปรแกรมที่ไม่ดี
โมดดิบ

คำตอบ:


90

elseบล็อกควรประกอบด้วยสิ่งที่คุณต้องการการทำงานเริ่มต้นที่จะเป็น

ไม่จำเป็นต้องหลีกเลี่ยงพวกเขาเพียงใช้ความระมัดระวังอย่างเหมาะสม

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

If (passwordCheck)
{
   letThemIn();
}
else
{
   displayMessage();
}

เช่นหากการตรวจสอบรหัสผ่านใช้งานได้ให้ปล่อยไว้มิฉะนั้นจะสามารถแสดงข้อความแสดงข้อผิดพลาดได้เสมอ

แน่นอนคุณสามารถเพิ่มการตรวจสอบเพิ่มเติมให้กับคุณตรรกะโดยใช้งบelse ifแยกต่างหากifมากกว่า


2
@ dave.b ในบริบทของตัวอย่างฉันเดาว่ามันจะเป็นปัญหาด้านความปลอดภัย แต่ถ้านี่คือทั่วทุกจุดในฐานรหัสที่คุณกำลังดูอยู่มันเป็นสัญญาณของผู้ที่เขียนมันต้องการมากกว่านั้นอีก การปฏิบัติ :)
RYFN

9
ใครบางคนสามารถอธิบายรายละเอียดเกี่ยวกับความปลอดภัยของเรื่องนี้ได้หรือไม่? if (! some) {do} else {do ​​b} และ if (some) {do b} else {do ​​a} ไม่เท่ากับตรรกะ? ฉันพยายามที่จะเข้าใจความแตกต่างในแง่ของความปลอดภัยของสิ่งนี้?
Chris

11
@Chris: ฉันคิดว่า OP ใช้ภาษาที่พิมพ์น้อย ดังนั้นpasswordCheckอาจจะมีอะไร fe nullซึ่งจะทำให้passwordCheck == falseการfalseและผู้ใช้จะช่วยให้การเข้าสู่ระบบเนื่องจากข้อผิดพลาดภายใน
Bobby

1
@Chris ความเข้าใจของฉันคือสถานะเริ่มต้นคือการอนุญาตให้เข้าถึงซึ่งไม่จำเป็นต้องแนะนำให้เลือก
RYFN

3
ใช่มันขึ้นอยู่กับภาษามาก ใน C # ที่ifต้องการ a bool, ตัวแปรจะต้องได้รับการกำหนดแน่นอนเส้นทางทั้งหมดจะต้องส่งกลับค่า ฯลฯ ฉันไม่สามารถคิดเหตุผลของคำสั่งifและelseจะมีความสำคัญนอกเหนือจากการอ่าน นั่นคือควรจะเทียบเท่ากับif(a){b();}{c();} if(!a){c();{b();}ใน JavaScript ในอีกทางหนึ่งคุณต้องระวังว่าpasswordCheckอาจเป็นundefinedเช่นนั้นได้
Tim Goodman

57

ELSEไม่ได้มีอะไรผิดปกติกับ ไม่ได้เป็นใหม่ELSE GOTOในความเป็นจริงการใช้สองIFs แทนELSEสามารถนำไปสู่ปัญหาต่าง ๆ

ตัวอย่างที่หนึ่ง:

if (this(is(a(very())==complex(check())))) {
   doSomething();
}

if (!this(is(a(very())==complex(check())))) {
   doTheOtherThing();
}

คุณเห็นสำเนาวางหรือไม่ มันแค่รอวันที่คุณเปลี่ยนและลืมอีกอัน

ตัวอย่างที่สอง:

foreach(x in y) {
  if (first_time) {
    first_time = false;
    doSomething();
  }

  if (!first_time) {
    doTheOtherThing();
  }
}

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


12
ฉันเห็นด้วยกับสิ่งนี้ คัดลอกการวางifคำสั่งและการแสดงออก inverting บูลของมันเพียงเพื่อหลีกเลี่ยงการelse- ตอนนี้ว่าเป็นโปรแกรมที่เขียนไม่ดี! ไม่เพียง แต่คุณทำรหัสซ้ำ ( การเขียนโปรแกรมไม่ดี ) แต่ยังทำให้ประสิทธิภาพลดลงด้วย (หากการตรวจสอบมีความซับซ้อนจริงๆตอนนี้คุณกำลังทำสองครั้ง - ba - เอ่อคุณรู้ว่าสิ่งที่พวกเขาพูดเกี่ยวกับการเพิ่มประสิทธิภาพก่อนกำหนด ทุกวันนี้ ... การเขียนโปรแกรมไม่ค่อยดี !)
gablin

บอกตามตรงว่าหากการตรวจสอบควรอยู่ในวิธีการของตนเองเพื่อส่งคืนจริง / เท็จ
billy.bob

ตัวอย่างที่ดีอย่าลืมประสิทธิภาพของการใช้ 2 หากตรวจสอบกับหนึ่งถ้าจับคู่กับอื่น ฉันจะสันนิษฐานในภาษาส่วนใหญ่ที่ใช้ if / else จะทำงานได้ดีกว่าการใช้สองคำสั่งถ้าข้อความที่มี one ใช้ไม่ได้อยู่ในเงื่อนไข
Chris

1
dave.b: แน่นอน แต่มันอาจเริ่มง่ายและเติบโตช้า ตัวอย่างการตรวจสอบที่ซับซ้อนของฉันอยู่ที่นี่เพื่อทำให้ปัญหาชัดเจนขึ้น
281377

3
ใช่ - และอย่าลืมว่าเงื่อนไขอาจมีผลข้างเคียงในภาษาส่วนใหญ่และถ้ามีฟังก์ชั่นในสภาวะที่คุณไม่สามารถบอกได้ด้วยการมอง
David Thornley

18

มี ELSE เสมอ ถ้าคุณเขียน

if(foo)
  bar();

คุณเขียนจริง

if(foo)
{
  bar();
}
else
{
   // do nothing
}

สิ่งที่คุณใส่ในเส้นทางอื่นเป็นความรับผิดชอบของคุณ


7
-1 คำตอบนี้ไร้สาระเกินไป ฉันไม่ได้บอกว่ามันไม่จริง มันเพิ่งพลาดจุด สิ่งที่คอมไพล์สร้างจากโค้ดของคุณไม่มีส่วนเกี่ยวข้องกับการเขียนโค้ดและข้อบกพร่องที่คุณเขียน

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

5
ภาษาอะไร ? ใน Java อย่างอื่นไม่ได้อยู่ในไบต์: P
IAdapter

@ acidzombie24 - เป็นวิธีที่ดีมากที่จะพิจารณาว่า 'อื่น' นั้นมาจากคำถามใด ๆ บางครั้งเป็นเพียง - ทำทุกอย่างอื่นใน fucntion แต่มันแสดงให้เห็นว่าคุณมีความคิดเกี่ยวกับเรื่องนี้
มาร์ติน Beckett

14

ฉันมักจะหลีกเลี่ยงตัวเองelseให้มากที่สุด แต่ก็ไม่ใช่ปัญหาด้านความปลอดภัย

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

if (checkPassword != OK) { displayMessage(); return; }

letThemIn();

นอกจากนี้ยังใช้กับforและwhileลูปที่ฉันจะใช้continueและbreakเมื่อใดก็ตามที่มันหลีกเลี่ยงระดับของการเยื้อง

คริสแลตต์เนอร์กล่าวว่าดีกว่าที่ฉันทำในLLVM มาตรฐานการเข้ารหัส


ฉันเห็นด้วย. "else" สร้าง "fork" ในใจและมนุษย์เราเป็นสิ่งมีชีวิตที่ต่อเนื่อง
user187291

Fyi เรียกว่าระบบรักษาความปลอดภัย
CaffGeek

@Chad: อาขอบคุณความสุขเสมอที่จะได้รับชื่อสำหรับสิ่งที่ :)
Matthieu เอ็ม

1
+1 นี่เป็นคำตอบเดียวที่ฉันสามารถยืนได้ซึ่งมีคะแนน> 1 *writes an answer*

ฉันไม่พยายามหลีกเลี่ยงอย่างอื่น แต่ฉันคิดว่าฉันเห็นด้วยกับสิ่งที่คุณเขียน ประเด็นก็คือสิ่งที่คุณกำลังทดสอบควรเป็นข้อยกเว้นไม่ใช่กรณีปกติ ( stackoverflow.com/questions/114342// ) นี่คือความล้มเหลวในการตรวจสอบความถูกต้องเป็นข้อยกเว้นและ (เท่านั้น) ที่ควรทดสอบ
hlovdal

5

จากนั้นเพียงแค่แทนที่พวกเขา

If (passwordCheck == true)
{
     letThemIn();
}
else
{
     displayMessage();
}

21
แล้วไงIf ((passwordCheck == true) == true)ล่ะ :-)
Hippo

1
มันเป็นสไตล์ของฉันเพื่อปรับปรุงการอ่าน คุณอาจเขียนว่า (! value) แต่ฉันชอบถ้า (value! = true)
Ahmet Kakıcı

7
มันไม่ได้ปรับปรุงความสามารถในการอ่าน มันแค่เพิ่มเสียงรบกวน แย่ยิ่งกว่านั้นคือโปรแกรมเมอร์ที่เขียนซ้อนกันหากสร้างเพียงเพราะพวกเขากลัวผู้ประกอบการบูลีน
ak2

3
หากชื่อตัวแปรเป็นคำอธิบายไม่มีเหตุผลว่าทำไม: ถ้า (someBooleanValue == จริง) ควรมีความจำเป็น สิ่งนี้จะดีกว่า: ถ้า (validPassword) {...
Mark Freedman

ฉันเพิ่งเปลี่ยนบล็อครหัสภายในคำถาม หากคุณอ่านความคิดเห็นแรกของฉันฉันบอกว่าฉันชอบใช้ if (value! = true) แทน if (! value) ฉันหวังว่าคุณจะเห็นความแตกต่างระหว่าง if (value) และ if (! value) ฉันหมายถึงฉันไม่ได้ใช้โอเปอเรเตอร์เสริม มิฉะนั้นคุณพูดถูก
Ahmet Kakıcı

3

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

ตอนนี้ฉันใช้elseเมื่อมันเหมาะสมโดยเฉพาะอย่างยิ่งสำหรับทางเลือกสั้น ๆ ง่ายๆ ดังที่กล่าวมาการทำสำเนาการทดสอบซ้ำจะทำให้เสียเวลา (โปรแกรมเมอร์และ CPU) แหล่งที่มาของความสับสนและต่อมาของข้อบกพร่อง (เมื่อมีการเปลี่ยนแปลงไม่ใช่อื่น)
บางครั้งฉันเพิ่มความคิดเห็นในelseส่วนเตือนสิ่งที่เป็นเงื่อนไข (โดยเฉพาะอย่างยิ่งถ้าifส่วนที่มีความยาวเช่นในรหัสดั้งเดิม) หรือสิ่งที่เป็นทางเลือก

โปรดทราบว่าผู้เสนอสุดยอดบางส่วนของการเขียนโปรแกรมฟังก์ชั่นเสนอที่จะกำจัดทั้งหมดifในความโปรดปรานของการจับคู่รูปแบบ ... เล็กน้อยเกินไปสำหรับรสนิยมของฉัน :-)


1
เป็นหมายเหตุข้างเคียง: หากคุณมีการสร้างถ้าในภาษาหน้าที่บริสุทธิ์ของคุณแล้วคุณจะต้องมีอย่างอื่น ทุกการแสดงออกต้องส่งคืนบางสิ่ง!
tokland

2

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

พยายามลบ ELSEs หากทำได้ - แต่อย่าหวาดระแวงกับมัน Steve McConnell เรียกรหัสเส้นตรงนี้ใน Code Complete คือมีเส้นทางที่ชัดเจนง่ายผ่านรหัสของคุณ

วิธีการลองสำหรับปัญหาเฉพาะของคุณ:

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

โดยทั่วไป - สิ่งต่อไปนี้อาจช่วยลด ELSEs ในรหัสของคุณ:

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

2
ฉันจะรวม "ย้ายการตรวจสอบบูลีนที่ซับซ้อนเป็นฟังก์ชันแยกต่างหาก"
gablin

2

ข้อสันนิษฐานของคุณเกี่ยวกับรหัสว่าเป็นความปลอดภัยรั่วอาจหรืออาจไม่เป็นจริงขึ้นอยู่กับภาษาที่คุณใช้ ในรหัส C มันอาจเป็นปัญหา (โดยเฉพาะอย่างยิ่งเพราะใน C บูลีนเป็นเพียง int ที่ไม่ใช่ศูนย์หรือศูนย์) - แต่ในภาษาที่พิมพ์อย่างรุนแรงที่สุด (เช่นการตรวจสอบประเภทรันไทม์) ถ้าpasswordCheckตัวแปรถูกประกาศเป็นบูลีน ไม่มีทางที่จะมอบหมายอย่างอื่นให้กับมันได้ ในความเป็นจริงทุกอย่างในเพรดิเคตifต้องแก้ไขเป็นบูลีนไม่ว่าคุณจะใช้โอเปอเรเตอร์บูลีนหรือเพียงแค่ใช้ค่า หากคุณจัดการให้มีวัตถุประเภทอื่นที่ถูกผูกไว้กับpasswordCheckรันไทม์จะทำให้เกิดข้อยกเว้นที่ผิดกฎหมายบางประเภท

ง่ายถ้า / อื่นสร้างจะง่ายต่อการอ่านมากกว่าถ้า / ถ้าสร้าง - และมีแนวโน้มที่จะเกิดปัญหาโดยไม่ตั้งใจน้อยลงถ้ามีคนพยายามที่จะพลิกโครงสร้าง ลองทำตัวอย่างเดียวกันเป็นวินาที

if(passwordCheck == false) {
    denyAccess();
}

if(passwordCheck) {
    letThemIn();
}

ความหมายของประโยคพิเศษร่วมกันที่คุณต้องการดำเนินการข้างต้นจะหายไป นั่นคือสิ่งที่ถ้า / อื่นสร้างสื่อถึง มีการดำเนินการสองสาขาที่ไม่เกิดร่วมกันโดยที่หนึ่งในนั้นจะทำงานเสมอ นี่เป็นส่วนสำคัญของการรักษาความปลอดภัย - ทำให้มั่นใจletThemInได้ว่าหลังจากคุณโทรมาdenyAccessแล้ว

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

if(passwordCheck) {
    letThemIn();
} else {
    denyAccess();
}

หมายเหตุ: ในการทำงานกับภาษาต่าง ๆ ฉันได้พัฒนา habbit เข้ารหัสที่ช่วยหลีกเลี่ยงคำถามที่ว่า "จะเกิดอะไรขึ้นถ้าเป็นสตริง" โดยพื้นฐานแล้วมันคือการใส่ค่าคงที่ก่อนในนิพจน์บูลีน ตัวอย่างเช่นแทนที่จะตรวจสอบpasswordCheck == falsefalse == passwordCheckผมตรวจสอบ นอกจากนี้ยังช่วยหลีกเลี่ยงปัญหาการมอบหมายโดยไม่ได้ตั้งใจใน C ++ ใช้วิธีนี้คอมไพเลอร์จะบ่นถ้าฉันพิมพ์แทน= ==ในภาษาเช่น Java และ C # คอมไพเลอร์จะปฏิบัติต่อการมอบหมายในข้อถ้าเป็นข้อผิดพลาด แต่ C ++ จะยอมรับอย่างมีความสุข นั่นเป็นเหตุผลที่ฉันมักจะทำการตรวจสอบโมฆะกับnullครั้งแรก

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


1

บอกว่าใช้ elseเมื่อการโปรแกรมไม่ดีก็เหมือนกับการพูดว่าการใช้otherwiseเมื่อการพูดไม่ดี

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


1

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

Else ในตัวมันเองก็ไม่เลว แต่ถ้าคุณใช้มันไม่ดีคุณสามารถเห็นผลที่ไม่พึงประสงค์ได้

นอกจากนี้ในส่วนที่เกี่ยวกับข้อความของคุณเกี่ยวกับ

"ฉันรู้ว่า passwordCheck น่าจะเป็นบูลีน แต่ฉันจะไม่วางความปลอดภัยของแอปพลิเคชันของฉันไว้"

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


ฉันไม่รู้ว่ามีภาษาที่ส่งคืนประเภทข้อมูลมากกว่าหนึ่งรายการ! คุณหมายถึงฟังก์ชั่น polymorphic หรือไม่? ฉันเชื่อว่าเมื่อใดก็ตามที่ฉันโอเวอร์โหลดฟังก์ชั่นมันจะคืนค่าประเภทข้อมูลเดียวกันเสมอแม้ว่ามันอาจใช้อาร์กิวเมนต์ที่แตกต่างกัน
Michael K

1
ในภาษาที่พิมพ์อย่างหลวม ๆ และโดยเฉพาะอย่างยิ่งใน PHP ฟังก์ชั่นสามารถส่งคืนข้อมูลได้มากกว่าหนึ่งประเภท เช่น: stristr- "ส่งคืนซับสตริงที่ตรงกันหากไม่พบเข็มส่งคืน FALSE"
Craige

@Michael ฟังก์ชั่น PHP สามารถคืนสิ่งที่คุณต้องการ ไม่มีการ จำกัด ประเภทข้อมูล ฟังก์ชันที่ซับซ้อนที่สุดของฉันคืนค่าเป็น true / false / null แต่ไม่มีสิ่งใด (ยกเว้นสามัญสำนึก) หยุดคุณเขียนฟังก์ชันที่ส่งคืน true / จำนวนเต็ม / null / string / float / array
TRiG

น่าสนใจ ฉันไม่เคยทำงานกับ PHP ขอบคุณสำหรับคำอธิบายแม้ว่า - อาจจะช่วยฉันในอนาคต! เช่นเดียวกับจาวาสคริปต์
Michael K

@Michael - ค่อนข้างคล้ายกับ Javascript แน่นอน
Craige

1

ก่อนอื่นเลย ฮ่า ๆ! ไม่มีเหตุผลเพื่อหลีกเลี่ยงการอื่นใดเลย มันไม่ได้เลวร้ายในทางใดทางหนึ่งรูปร่างหรือรูปแบบ

หากมีสิ่งใดรหัสควรเป็น

if(!IsLoggedIn) { ShowBadLoginOrNoAccessPage(); return }

ไม่มีสอง ifs อยู่ตรงนั้นและมันไม่มีอีกแล้ว นี่คือสิ่งที่ฉันทำในแอพทั้งหมดของฉันยกเว้นแอพที่ฉันมีข้อยกเว้น มีการยกเว้นข้อผิดพลาดในฟังก์ชันของฉันซึ่งตรวจสอบ URL สำหรับหน้าที่เหมาะสมในการแสดง (หรืออีกทางหนึ่งฉันสามารถวางฟังก์ชัน catch / check ในข้อผิดพลาด asp.net) มันพิมพ์หน้าทั่วไปที่ระบุว่าไม่อนุญาตหรือข้อความอะไรก็ตามที่ฉันใช้ในข้อยกเว้น (ฉันตรวจสอบประเภทของข้อยกเว้นเสมอและตั้งรหัสสถานะ http)

-Edit- ดังที่แสดงในตัวอย่าง ammoQ สอง ifs ไร้สาระ จริงๆ แล้วก็ดีหรือดีกว่าถ้ามี หากมีสิ่งใดที่ควรหลีกเลี่ยง (แม้ว่าฉันจะไม่ได้เป็นส่วนตัว แต่ฉันใช้ผลตอบแทนและทำลายเป็นจำนวนมาก) เนื่องจากมีการกล่าวถึงการใช้โค้ดมากขึ้นเพื่อเพิ่มโอกาสในการเกิดข้อบกพร่อง ดูCyclomatic Complexity

- แก้ไข 2- หากคุณกังวลเกี่ยวกับการใช้งาน / อื่น ๆ ฉันจะทราบด้วยว่าการตั้งค่าของฉันคือการวางบล็อคโค้ดที่สั้นที่สุดไว้ที่ด้านบนเช่น

if(cond == false) {
    a()
    b()
    c()
    onetwothree()
}
else
{
    a()
    b()
    c()
    more()
    onetwothree()
    code()
    longer()
}

ค่อนข้างแล้ว

if(cond) 
{
    a()
    b()
    c()
    more()
    onetwothree()
    code()
    longer()
}
else
{
    a()
    b()
    c()
    onetwothree()
}

0

ฉันชอบที่จะตั้งค่าเริ่มต้นก่อนที่จะมีเงื่อนไขเมื่อฉันสามารถ ฉันรู้สึกว่ามันอ่านง่ายขึ้นเล็กน้อยและชัดเจนกว่านี้เล็กน้อย แต่นี่เป็นเพียงการตั้งค่า ฉันมีแนวโน้มที่จะพยายามหลีกเลี่ยงเงื่อนไขเชิงลบในรหัสของฉัน ฉันไม่ได้เป็นแฟนตัวยงของการตรวจสอบ! foo หรือ false == foo และฉันรู้สึกว่าอย่างอื่นมีลักษณะเทียบเท่ากับเงื่อนไขเชิงลบ

foo = bar;

if ('fubar' == baz) {
    foo = baz;
}

แทน ...

if ('fubar' == baz) {
    foo = baz;
} else {
    foo = bar;
}

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


0

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

เป็นตัวอย่างหนึ่งผู้ประกอบการที่ประกอบไปด้วยสามคนก็มักจะเป็นผู้สมัครที่ดี:

If VIP Then 
  Discount = .25
Else
  Discount = 0
End If
Total = (1 - Discount) * Total

ใช้วิธีการที่ประกอบไปด้วย:

Discount = VIP ? .25 : 0
Total = (1 - Discount) * Total

ผู้ประกอบการ Ternary เปลี่ยนการแยกทางไปทางขวาอย่างเหมาะสม

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