ค่าคงที่แบบอักขระเดียวดีกว่าตัวอักษรจริงหรือไม่


127

เมื่อเร็ว ๆ นี้ฉันได้พบกับชั้นเรียนที่ให้ตัวละครทุกตัวเป็นค่าคงที่ ทุกอย่างจากการCOMMA BRACKET_OPENสงสัยว่าสิ่งนี้จำเป็นหรือไม่ ฉันอ่าน"บทความ"ซึ่งแสดงว่าอาจเป็นประโยชน์ในการดึงตัวอักษรเดียวให้อยู่ในค่าคงที่ ดังนั้นฉันสงสัย

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

เหตุผลเดียวที่ฉันเห็นการใช้ค่าคงที่แทนตัวอักษรคือการทำให้โค้ดอ่านง่ายขึ้น แต่เป็นcity + CharacterClass.COMMA + stateตัวอย่างที่อ่านได้ง่ายกว่าจริงcity + ',' + stateหรือ

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


12
เกี่ยวข้องกันมาก: programmers.stackexchange.com/questions/221034/…
Blrfl

33
อืม ... มันอาจจะมีประโยชน์สำหรับสถานที่ต่างกันใช่ไหม ตัวอย่างเช่นบางภาษาใช้ guillements (เครื่องหมายคำพูดมุม«และ») เป็นเครื่องหมายคำพูดแทนที่จะเป็นมาตรฐานของภาษาอังกฤษ"(หรือที่ดูดีกว่าและ) นอกเหนือจากนั้นมันก็ดูเหมือนชุดอักขระเวทย์มนตร์ สมมติว่าทั้งสองกรณีของCharacterClassที่เรียกว่าenglishCharsและfrenchCharsก็เป็นไปได้ว่าenglishChars.LEFT_QUOTEอาจจะมีในขณะที่อาจจะมีfrenchChars.LEFT_QUOTE «
Justin เวลา

4
มีหลายรูปแบบที่แตกต่างกันในเครื่องหมายจุลภาค: en.wikipedia.org/wiki/Comma#Comma_variants - บางทีนี่อาจไม่ใช่ความคิดที่โง่เง่าโดยเฉพาะอย่างยิ่งถ้าซอร์สโค้ดของคุณสามารถเข้ารหัสเป็น utf-8 ได้
Aaron Hall

21
ในกรณีของคุณมันเหมือนกับการเรียกตัวแปร "number" ค่าคงที่ของคุณควรถูกเรียกว่า DELIMITER หรือควรเป็น CITY_STATE = "{0}, {1}"
the_lotus

13
บทความที่คุณเชื่อมโยงนั้นแย่มาก ค่าคงที่ไม่ควรถูกโยนลงในถังเช่นนั้น วางไว้บนคลาสที่พวกเขามีบริบท: โดยพื้นฐานแล้วคลาสที่มีค่าคงที่จะจัดเตรียมบริบทที่ใช้ค่าคงที่ ยกตัวอย่างเช่นของ File.separatorJava ชั้นเรียนจะบอกประเภทของตัวคั่น มีคลาสที่ชื่อConstsหรือConstantsไม่ให้บริบทและทำให้ค่าคงที่ยากต่อการใช้อย่างถูกต้อง

คำตอบ:


184

Tautology :

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

สามัญสำนึกบอกคุณว่าconst char UPPER_CASE_A = 'A';หรือconst char A = 'A'ไม่เพิ่มอะไรนอกจากการบำรุงรักษาและความซับซ้อนในระบบของคุณ const char STATUS_CODE.ARRIVED = 'A'เป็นกรณีอื่น

ค่าคงที่ควรจะเป็นตัวแทนของสิ่งต่าง ๆ ที่ไม่เปลี่ยนรูปในขณะทำงาน แต่อาจจะต้องมีการแก้ไขในอนาคตในเวลารวบรวม เมื่อใดที่จะconst char A =ถูกต้องเท่ากับสิ่งอื่นAใด

หากคุณเห็นpublic static final char COLON = ':'ในรหัส Java ให้หาคนที่เขียนและทำลายแป้นพิมพ์ของพวกเขา หากการเป็นตัวแทนCOLONตลอดการเปลี่ยนแปลงจาก:คุณจะมีฝันร้ายบำรุงรักษา

obfuscation:

จะเกิดอะไรขึ้นเมื่อมีคนเปลี่ยนเป็นCOLON = '-'เพราะพวกเขากำลังใช้ที่ต้องการ-ทุกที่แทน? คุณจะเขียนการทดสอบหน่วยที่พูดโดยทั่วไปassertThat(':' == COLON)สำหรับconstการอ้างอิงทุก ๆ ครั้งเพื่อให้แน่ใจว่าจะไม่เปลี่ยนแปลง มีเพียงคนที่จะแก้ไขการทดสอบเมื่อพวกเขาเปลี่ยนพวกเขา?

หากมีคนแย้งว่าpublic static final String EMPTY_STRING = "";มีประโยชน์และเป็นประโยชน์จริง ๆคุณแค่ผ่านการรับรองความรู้และละเว้นสิ่งเหล่านี้อย่างปลอดภัย

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

การติดต่อกัน:

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

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

การเชื่อมต่อ:

นอกจากนี้ยังมีคลาสที่ไม่เกี่ยวข้องจำนวนมากเข้าด้วยกันเพราะพวกเขาทั้งหมดจบลงด้วยการอ้างอิงไฟล์ที่ไม่เกี่ยวข้องกับสิ่งที่พวกเขาทำ

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

หากคุณใช้ชื่อที่ดีกว่าเช่นDELIMITER = ','คุณจะยังคงมีปัญหาเดียวกันเพราะชื่อนั้นเป็นชื่อสามัญและไม่มีความหมาย ','กำหนดใหม่ค่าไม่ไม่มากที่จะช่วยให้ทำการวิเคราะห์ผลกระทบมากกว่าการค้นหาและแทนที่สำหรับตัวอักษร เพราะบางรหัสใช้มันและต้องการ,และใช้รหัสอื่น แต่ต้องการ;ตอนนี้? ยังคงต้องดูการใช้งานด้วยตนเองทุกครั้งและเปลี่ยน

ในป่า:

ฉันเพิ่งปรับปรุง1,000,000+ LOCใบสมัครที่มีอายุ 18 ปีขึ้นไป public static final COMMA = SPACE + "," + SPACE;มันมีสิ่งที่ต้องการ มันไม่ได้ดีไปกว่าการฝังไว้ใน" , "ตำแหน่งที่ต้องการ

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

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

เช่นเดียวกันกับตัวอักษรมีหลายUPPER_CASE_A, A, UPPER_A, A_UPPERที่มากที่สุดของเวลาเท่ากับแต่ในบางกรณีไม่ได้A สำหรับตัวละครเกือบทุกตัว แต่ไม่ใช่ตัวละครทุกตัว

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

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

ฉัน refactored ทั้งหมดยุ่งเหยิงนี้และ inline tautologies ทั้งหมดและจ้างวิทยาลัยใหม่มีประสิทธิผลมากขึ้นเพราะพวกเขาไม่ต้องตามล่าผ่านหลายระดับของสิ่งที่constอ้างอิงเหล่านี้ชี้ไปเพราะพวกเขาไม่น่าเชื่อถือในสิ่งที่พวกเขาถูกตั้งชื่อ vs สิ่งที่พวกเขามี


112
บางทีคุณควรเพิ่มตัวอย่างตัวอย่าง: const char DELIMITER = ':'มีประโยชน์จริง ๆ
Bergi

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

39
@ กลไก: เราสามารถหยุดคิดถึงสิ่งเหล่านี้ว่ามีประโยชน์ในบริบทของการจัดการการเปลี่ยนแปลง พวกมันยังอยู่ พวกเขาไม่เปลี่ยนแปลง คิดว่าพวกเขาเป็นประโยชน์ในบริบทของมนุษย์การค้นหาและทำความเข้าใจความหมายของรหัส รู้สิ่งที่เป็นคีย์มูลค่าคู่คั่นถูกมากมีประโยชน์มากขึ้นกว่ารู้ว่ามันคือลำไส้ใหญ่; ว่าเป็นความจริงเกี่ยวกับโดเมนความหมายของความกังวลของโปรแกรมไม่ได้ของไวยากรณ์
Eric Lippert

15
@EricLippert: ฉันเห็นจุดของคนอื่นที่นี่ที่ชี้ให้เห็นว่าสิ่งเดียวที่รับประกันได้ว่าconstมันจะไม่เปลี่ยนแปลงที่รันไทม์ (หลังจากรวบรวม) แม้ว่าฉันจะเห็นด้วยกับคุณว่าความหมายของความหมายของconstมันคือ สำคัญกว่าการใช้เป็นเครื่องมือในการจัดการการเปลี่ยนแปลง ที่กล่าวว่าฉันสามารถจินตนาการอย่างแน่นอนconst EARLIEST_OS_SUPPORTEDซึ่งไม่เพียง แต่มีความหมายทางความหมาย แต่จะเปลี่ยนแปลงตลอดเวลาเมื่อโปรแกรมวิวัฒนาการและ cruft เก่าจะถูกลบออก
Robert Harvey

16
@DanielJour: ดังนั้นนี่คืออาร์กิวเมนต์ที่สามสำหรับEMPTY_STRING; IDE ที่ได้รับการออกแบบมาอย่างดีจะแสดงเครื่องมือที่ช่วยให้ฉันสามารถปฏิบัติกับเอนทิตีนี้ได้อย่างเป็นสัญลักษณ์แทนที่จะเป็นวากยสัมพันธ์ คุยนี้ให้อาร์กิวเมนต์ที่สี่: ที่ห้องสมุดของเครื่องมือวิเคราะห์รหัสที่ตั้งอยู่ด้านล่าง IDE อาจอนุญาตให้มีการขั้นสูงการเขียนโปรแกรมการวิเคราะห์ของรหัสที่ถูกต้องในระดับสัญลักษณ์ นักพัฒนาที่ปรารถนาจะใช้ประโยชน์จากเครื่องมือที่ล้ำหน้ากว่าที่เขียนไว้เมื่อ 40 ปีก่อนจำเป็นต้องทำการเปลี่ยนแปลงเพียงเล็กน้อยต่อนิสัยของพวกเขาเพื่อเก็บเกี่ยวผลตอบแทนจากการใช้เครื่องมือขั้นสูง
Eric Lippert

145

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

ไม่ได้อย่างแน่นอน. นี่คือไม่ได้ทุกเหตุผลที่จะใช้ค่าคงที่เพราะคงไม่เปลี่ยนแปลงโดยความหมาย ถ้าค่าคงที่เคยเปลี่ยนแปลงนั่นก็ไม่ใช่ค่าคงที่ใช่ไหม?

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

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

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


42
ในขณะที่ฉันเห็นด้วยกับวิญญาณของสิ่งที่คุณพูดที่นี่ประโยคที่สอง / สามของคุณไม่ถูกต้องจริงๆ ค่าคงที่สามารถเปลี่ยนแปลงระหว่างเวอร์ชันของไฟล์ อันที่จริงโปรแกรมส่วนใหญ่ที่ฉันเขียนมีค่าคงที่ชื่อคล้ายMY_VERกันซึ่งมีหมายเลขเวอร์ชันปัจจุบันของโปรแกรมซึ่งสามารถใช้งานได้ตลอดเวลาที่เหลือของโปรแกรมแทนที่จะเป็นสายมายากลเช่น "5.03.427.0038" สิทธิประโยชน์เพิ่มเติมคือเมื่อคุณบอกว่ามันให้ข้อมูลความหมาย
Monty Harder

50
เพื่อความเป็นธรรมประเด็นของค่าคงที่คือมันไม่เปลี่ยนแปลงระหว่างรันไทม์หลังจากถูกกำหนดค่าเริ่มต้นไม่ใช่ว่าจะไม่เปลี่ยนระหว่างการคอมไพล์ จากมุมมองของคอมไพเลอร์ประเด็นก็คือคอมไพเลอร์สามารถตั้งสมมติฐานว่าโปรแกรมไม่สามารถแก้ไขได้ ไม่ว่าโปรแกรมเมอร์จะได้รับอนุญาตให้แก้ไขหรือไม่เมื่อพวกเขาทำการคอมไพล์ใหม่จะไม่เปลี่ยนค่าคงที่ อาจมีบางกรณีที่ซอฟต์แวร์ใช้ค่าแบบอ่านอย่างเดียวจากฮาร์ดแวร์อาจโดยการยกเลิกการใช้const volatile T*ตัวชี้ไปยังที่อยู่ที่กำหนดไว้ล่วงหน้า ในขณะที่โปรแกรมไม่สามารถเปลี่ยนแปลงได้ฮาร์ดแวร์สามารถ
Justin เวลา

6
@MontyHarder: จุดดี ความคิดเห็นของฉันได้รับแจ้งจากความจริงที่ว่าฉันมักจะใช้ภาษาที่แยกความแตกต่างระหว่างค่าคงที่ - ซึ่งจะต้องไม่เปลี่ยนแปลงตลอดไป - และตัวแปรที่อาจได้รับมอบหมายเพียงครั้งเดียว - ซึ่งสามารถเปลี่ยนจากรุ่นเป็นรุ่นเรียกใช้หรืออะไรก็ตาม ค่าคงที่และตัวแปรต่างกัน หนึ่งยังคงเหมือนเดิมและแตกต่างกันเมื่อเวลาผ่านไป
Eric Lippert

7
@SteveCox: ฉันเห็นด้วย; วิธีที่ C / C ++ มีลักษณะ "const" แปลกและใช้งานไม่ได้ คุณสมบัติที่ฉันต้องการของค่าคงที่คือค่าของมันไม่เปลี่ยนแปลงไม่ใช่ว่าฉันถูก จำกัด จากการเปลี่ยนแปลงในบางฟังก์ชั่น แต่ไม่ใช่ในคุณสมบัติอื่น
Eric Lippert

15
"นี่ไม่ใช่เหตุผลที่จะใช้ค่าคงที่เพราะค่าคงที่ไม่เปลี่ยนแปลงตามคำจำกัดความหากค่าคงที่เคยเปลี่ยนไปแล้วมันไม่คงที่ใช่หรือไม่" การเปลี่ยนค่าคงที่ที่เวลาคอมไพล์ (ไม่ใช่การรันไทม์อย่างชัดเจน) เป็นเรื่องปกติอย่างสมบูรณ์ นั่นเป็นเหตุผลที่คุณทำให้พวกเขามี "สิ่ง" ที่มีป้ายกำกับอย่างชัดเจนตั้งแต่แรก แน่นอนคงที่ของ OP ที่มีขยะ แต่คิดว่าสิ่งที่ต้องการconst VERSION='3.1.2'หรือconst KEYSIZE=1024หรืออะไรก็ตาม
AnoE

61

ไม่นั่นเป็นใบ้

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

แต่การทำให้ค่าคงที่เพราะ "สายอักขระเวทมนต์ไม่ดี" เป็นเพียงการปลูกฝังการขนส่งสินค้า


8
การแปลหลายภาษามักจะซับซ้อนกว่าค่าคงที่ของสตริง ตัวอย่างเช่นบางภาษาต้องการตัวคั่นรายการระหว่างรายการทั้งหมดในขณะที่คนอื่น ๆ ยกเว้นตัวคั่นก่อนรายการสุดท้าย ดังนั้นคงที่มักจะหนึ่งต้องไม่ท้องถิ่น แต่ที่มีการแปลกฎ
Vlad

19
ที่จริงแล้วตัวคั่นหลักพันนั้นไม่จำเป็นต้องเป็นตัวคั่นหลักพันในตำแหน่งที่ตั้งอื่น (จีน / ญี่ปุ่น) มันไม่ได้ตั้งค่าแม้กระทั่งหลังจากตัวเลขคงที่ (อินเดีย) โอ้และอาจมีตัวคั่นที่แตกต่างกันขึ้นอยู่กับว่าเป็นตัวคั่น 1,000 หรือตัวคั่น 1000000 (เม็กซิโก) แต่นั่นเป็นปัญหาที่น้อยกว่าการไม่ใช้ตัวเลข ASCII 0-9 ในบางภาษา (Farsi) ux.stackexchange.com/questions/23667/…
ปีเตอร์

1
@Vlad Localization นั้นซับซ้อนกว่านั้นมากอย่างไรก็ตามตัวคั่นหลักพันเป็นตัวอย่างที่รู้จักกันดีที่ผู้คนรู้จัก

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

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

29

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

static const wchar_t HYPHEN = '-';
static const wchar_t MINUS = '-';
static const wchar_t EM_DASH = '-';

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

static const wchar_t HYPHEN = '-';
static const wchar_t MINUS = '\u2122';
static const wchar_t EM_DASH = '\u2014';

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

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


สำหรับฉันนี่เป็นเหตุผลที่ถูกต้องเพียงอย่างเดียวที่อาจสร้างค่าคงที่ตัวละคร
FP

2
การใช้-เป็นประ em นั้นค่อนข้างทำให้เข้าใจผิด ... มันสั้นมากสำหรับแบบอักษรส่วนใหญ่ (มันสั้นกว่าขีดสั้นด้วย)
Paŭlo Ebermann

ตกลงไม่ใช่ตัวอย่างที่ดีที่สุด ฉันเริ่มต้นด้วยstrings แทนที่จะเป็นwchar_ts และใช้ระเบียบการเขียนด้วยลายมือมาตรฐานของ"--"เส้นประ แต่ตัวอย่างดั้งเดิมคือการใช้อักขระเดียวดังนั้นฉันจึงเปลี่ยนไปใช้จริงกับคำถาม มีหลายคนที่พิมพ์-เพื่อขีดกลางโดยเฉพาะเมื่อทำงานในฟอนต์พิทช์คงที่
Adrian McCarthy

1
@ PaŭloEbermannไม่ตามเนื้อผ้า em คือความกว้างของตัวอักษร 'm' ของแบบอักษรและ en dash คือความกว้างของอักขระ 'n'
Dizzley

@Dizzley ใช่และเครื่องหมายขีดคั่นกว้าง <n-width <m-width
Paŭlo Ebermann

22

ค่าคงต้องเพิ่มความหมาย

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

หากคุณใช้เครื่องหมายจุลภาคเพื่อจุดประสงค์และต้องการใช้ค่าคงที่ที่กำหนดชื่อให้ตั้งชื่อตามวัตถุประสงค์ ตัวอย่าง:

  • city + CharacterClass.COMMA + state = ไม่ดี
  • city + CITY_STATE_DELIMITER + state = ดี

ใช้ฟังก์ชั่นสำหรับการจัดรูปแบบ

ฉันชอบFormatCityState(city, state)และไม่สนใจว่ารูปร่างของฟังก์ชั่นนั้นจะดูเป็นอย่างไรถ้ามันสั้นและผ่านการทดสอบ


1
อ่า แต่เครื่องหมายจุลภาคนั้นไม่ใช่เครื่องหมายจุลภาคเหมือนกันเสมอไป ฉันสามารถกำหนด COMMA = '\ u0559' หรือ '\ u060C' เป็นต้น (ดู Unicode) หรือเปลี่ยนเป็นตัวแปรในภายหลังและอ่านจากไฟล์ปรับแต่ง ด้วยวิธีนี้มันจะยังคงมีความหมายเหมือนกันแต่เป็นเพียงคุณค่าที่แตกต่าง วิธีการเกี่ยวกับที่
นาย Lister

2
@MrLister: YAGNI หากคุณมีความต้องการนั้น: ยอดเยี่ยม! คุณมีทางออกที่ดี แต่ถ้าคุณทำไม่ได้ - อย่าเกะกะรหัสของคุณเพราะบางทีวันหนึ่งคุณอาจจะ นอกจากนี้จากประสบการณ์ของฉันถ้าคุณพยายามที่จะแนะนำ abstractions โดยไม่มีฟังก์ชั่นใน codebase ของคุณผู้คนไม่ค่อยมีความสม่ำเสมอ ดังนั้นแม้ว่าคุณจะกำหนด COMMA ด้วยความตั้งใจที่จะใช้ codepoint อื่น ๆ ในโปรแกรมที่มีขนาดและอายุเพียงพอที่ตัวเลือกมีความสำคัญคุณก็จะพบว่าค่าคงที่ไม่ควรใช้ทุกที่ เคย (และในทางกลับกันอาจถูกใช้อย่างไม่เหมาะสมด้วย)
Eamon Nerbonne

17

แนวคิดที่ว่าค่าคงที่ COMMA นั้นดีกว่า','หรือ","ค่อนข้างง่ายที่จะทำการ debunk แน่นอนว่ามีบางกรณีที่เหมาะสมเช่นการfinal String QUOTE = "\"";บันทึกอย่างหนักในการอ่านโดยไม่มีเครื่องหมายทับ แต่ยกเว้นตัวควบคุมภาษาเช่น\ 'และ"ฉันไม่พบว่ามันมีประโยชน์มาก

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

สิ่งที่มีประโยชน์คือให้ชื่อที่มีประโยชน์แก่พวกเขา และใช่บางครั้งค่าคงที่หลายค่าจะมีเนื้อหาเหมือนกัน แต่มีชื่อต่างกัน final String LIST_SEPARATOR = ","เช่น

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


วิธีการเกี่ยวกับการกำหนด DISP_APOSTROPHE แบบมีเงื่อนไขเป็น ASCII 0x27 หรืออักขระเครื่องหมายคำพูดด้านขวาเดียวของ Unicode (ซึ่งเป็นการแปลที่เหมาะสมกับการพิมพ์ที่เหมาะสมมากขึ้น) ขึ้นอยู่กับแพลตฟอร์มเป้าหมาย
supercat

3
จริงQUOTEตัวอย่างเช่นพิสูจน์ให้เห็นว่ามันเป็นความคิดที่ไม่ดีเช่นกันเพราะคุณกำหนดสิ่งที่ทั่วไป / เรียกขานกัน DOUBLE QUOTEและQUOTEหมายถึงการSINGLE_QUOTEที่เรียกอื่น ๆ APOSTROPHEได้อย่างถูกต้องว่า

3
@JarrodRoberson ฉันไม่รู้สึกว่าคำพูดหมายถึงคำพูดเดียวส่วนตัว - แต่นั่นเป็นอีกเหตุผลที่ดีที่จะลบความคลุมเครือที่คุณสามารถ!
corsiKa

2
ฉันไม่ชอบQUOTEตัวอย่างด้วยเหตุผลเพิ่มเติม - มันทำให้สายการอ่านที่ถูกสร้างด้วยมันยิ่งยาก"Hello, my name is " + QUOTE + "My Name" + QUOTEนี่เป็นตัวอย่างที่น่ารำคาญ แต่ก็ยังดูไม่ดี โอ้แน่นอนว่าคุณสามารถใช้โทเค็นแทนที่โทเค็นแทนการต่อข้อมูล"Hello, my name is %sMy Name%s".format(QUOTE, QUOTE)ได้ แต่เดี๋ยวก่อนลองทำโทเค็นที่จัดทำดัชนี"Hello, my name is {0}My Name{0}".format(QUOTE)ไม่ดีกว่านี้มาก สตริงที่ไม่สำคัญที่สร้างขึ้นด้วยเครื่องหมายคำพูดในนั้นจะยิ่งแย่ลง
VLAZ

2
@corsiKa - ฉันจะอยู่กับคำพูดจริงที่หลบหนี ถ้าฉันพลาดการหลบหนี IDE ที่ฉันใช้จะบ่นทันที รหัสส่วนใหญ่จะไม่รวบรวมเช่นกัน มันค่อนข้างง่ายที่จะมองเห็น มันง่ายแค่ไหนที่จะทำผิดพลาดเมื่อทำ"My name is" + QUOTE + "My Name" + QUOTEจริงฉันทำผิดที่เหมือนกันสามครั้งในการเขียนความคิดเห็นข้างต้น คุณสามารถมองเห็นมันได้หรือไม่ ถ้าจะใช้เวลาคุณนิดก็เป็นพื้นที่ที่หายไปหลังจากที่เป็น คุณจัดรูปแบบสตริงหรือไม่ ในกรณีนี้สตริงที่มีโทเค็นหลายรายการที่จะแทนที่จะยิ่งแย่ลงกว่าเดิม ฉันจะใช้มันอย่างไรเพื่อให้อ่านได้ง่ายขึ้น?
VLAZ

3

ฉันทำงานเขียน lexers และ parsers และใช้ค่าคงที่จำนวนเต็มเพื่อแสดงเทอร์มินัล เทอร์มินัลอักขระเดี่ยวมีรหัส ASCII เป็นค่าตัวเลขเพื่อประโยชน์ของความเรียบง่าย แต่โค้ดอาจเป็นอย่างอื่นทั้งหมด ดังนั้นฉันมี T_COMMA ที่ได้รับรหัส ASCII สำหรับ ',' เป็นค่าคงที่ อย่างไรก็ตามยังมีค่าคงที่สำหรับ nonterminals ซึ่งถูกกำหนดเป็นจำนวนเต็มเหนือชุด ASCII จากการดูที่ตัวแยกวิเคราะห์เช่น yacc หรือ bison หรือ parsers ที่เขียนโดยใช้เครื่องมือเหล่านี้ฉันได้รับความประทับใจว่าเป็นสิ่งที่ทุกคนทำ

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

ฉันสามารถนึกถึงกรณีที่โดดเดี่ยวอีกสองสามแห่งซึ่งมันอาจสมเหตุสมผลที่จะใช้ค่าคงที่แทนที่จะใช้ตัวอักษรที่สอดคล้องกัน ตัวอย่างเช่นคุณอาจกำหนด NEWLINE ให้เป็นตัวอักษร '\ n' ในกล่อง unix แต่ '\ r \ n' หรือ '\ n \ r' หากคุณอยู่ใน windows หรือ mac box เช่นเดียวกับการแยกวิเคราะห์ไฟล์ซึ่งเป็นตัวแทนของข้อมูลแบบตาราง คุณอาจกำหนดค่าคงที่ FIELDSEPARATOR และ RECORDSEPARATOR ในกรณีเหล่านี้คุณกำหนดค่าคงที่เพื่อแสดงถึงตัวละครที่ทำหน้าที่บางอย่าง ถึงกระนั้นถ้าคุณเป็นโปรแกรมเมอร์มือใหม่บางทีคุณอาจตั้งชื่อตัวคั่นฟิลด์คงที่ COMMA โดยไม่ทราบว่าคุณควรจะเรียกมันว่า FIELDSEPARATOR และเมื่อถึงเวลาที่คุณรับรู้รหัสจะอยู่ในช่วงการผลิตและต่อไป โครงการ,

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

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


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

3

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

abstractions ที่ดีทำให้โค้ดใช้งานง่ายในอีกด้านหนึ่งและง่ายต่อการดูแลรักษาในอีกทางหนึ่ง

ฉันเห็นด้วยโดยสิ้นเชิงว่าDELIMITER=':'ตัวเองและในตัวของมันเองเป็นนามธรรมที่น่าสงสารและดีกว่าCOLON=':'(เพราะคนหลังนั้นยากจนโดยสิ้นเชิง)

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

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

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

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


2

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

ในทั้งสองกรณีการใช้สัญลักษณ์ที่มีชื่อเช่นนั้นCOMMAจะช่วยให้เกิดการเกาะติดกันของผลิตภัณฑ์ที่แยกจากกัน ค่าดังกล่าวมักจะเกินดุลค่าใช้จ่ายของสัญกรณ์ verbose มากเกินไป


2

สังเกตว่าคุณกำลังพยายามทำรายการ

ดังนั้น refactor เป็น: String makeList(String[] items)

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


0

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

อย่างไรก็ตามมีอย่างน้อยสองกรณีที่เหมาะสมที่จะประกาศค่าคงที่ซึ่งชื่ออธิบายเนื้อหาของพวกเขาอย่างแน่นอนและคุณไม่สามารถเปลี่ยนค่าได้โดยไม่ต้องเปลี่ยนชื่อค่าคงที่:

  • PI = 3.14159ค่าคงที่ทางคณิตศาสตร์หรือทางกายภาพเช่น ที่นี่บทบาทของค่าคงที่คือทำหน้าที่ช่วยในการจำเนื่องจากชื่อสัญลักษณ์PIสั้นกว่ามากและอ่านได้ง่ายกว่าค่าที่แสดงไว้
  • รายการสัญลักษณ์ที่ครบถ้วนสมบูรณ์ในตัวแยกวิเคราะห์หรือปุ่มบนแป้นพิมพ์ มันอาจสมเหตุสมผลที่จะมีรายการค่าคงที่ที่มีอักขระ Unicode ส่วนใหญ่หรือทั้งหมดและนี่คือที่ที่เคสของคุณอาจตกลง ตัวละครบางตัวเช่นAชัดเจนและเป็นที่รู้จักอย่างชัดเจน แต่คุณสามารถบอกАและAแยกได้อย่างง่ายดาย? คนแรกคือซีริลลิАตัวอักษรในขณะที่หลังเป็นภาษาละตินตัวอักษร A พวกมันเป็นตัวอักษรที่แตกต่างกันแสดงด้วยจุดรหัส Unicode ที่แตกต่างกันถึงแม้ว่าพวกมันจะเหมือนกัน ฉันอยากจะมีค่าคงที่CYRILLIC_CAPITAL_AและLATIN_CAPITAL_Aในรหัสของฉันมีอักขระที่ดูคล้ายเกือบสองตัว แน่นอนว่ามันไม่มีประโยชน์หากคุณรู้ว่าคุณจะทำงานกับอักขระ ASCII ที่ไม่มี Cyrillic เท่านั้น ในทำนองเดียวกัน: ฉันใช้ตัวอักษรละตินทุกวันดังนั้นถ้าฉันกำลังเขียนโปรแกรมที่ต้องการตัวอักษรจีนฉันอาจต้องการใช้ค่าคงที่แทนที่จะใส่ตัวอักษรที่ฉันไม่เข้าใจ สำหรับคนที่ใช้ตัวอักษรจีนแบบวันต่อวันตัวอักษรจีนอาจจะชัดเจน แต่ภาษาละตินอาจจะง่ายกว่าที่จะแสดงเป็นค่าคงที่ที่มีชื่อ ดังนั้นอย่างที่คุณเห็นมันขึ้นอยู่กับบริบท ถึงกระนั้นห้องสมุดอาจมีค่าคงที่เชิงสัญลักษณ์สำหรับอักขระทั้งหมดเนื่องจากผู้เขียนไม่ทราบล่วงหน้าว่าจะใช้ไลบรารีอย่างไรและอักขระใดที่อาจต้องการค่าคงที่เพื่อปรับปรุงความสามารถในการอ่านในแอปพลิเคชันเฉพาะ

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


-1

อาจจะ.

ค่าคงที่อักขระเดี่ยวค่อนข้างยากที่จะแยกแยะ ดังนั้นจึงค่อนข้างง่ายที่จะพลาดข้อเท็จจริงที่ว่าคุณกำลังเพิ่มช่วงเวลาแทนที่จะเป็นเครื่องหมายจุลภาค

city + '.' + state

ในขณะที่เป็นความผิดพลาดที่ค่อนข้างยากที่จะทำ

city + Const.PERIOD + state

ขึ้นอยู่กับความเป็นสากลและสภาพแวดล้อมโลกาภิวัตน์ความแตกต่างระหว่างเครื่องหมายอัญประกาศ ASCII และเครื่องหมายอัญประกาศเปิดและปิดของ Windows-1252 (หรือเครื่องหมายอัญประกาศคู่ ASCII และเครื่องหมายอัญประกาศคู่เปิด ASCII และ Windows-1252 อาจมีความสำคัญและเป็นเรื่องยากที่จะมองเห็นภาพ ที่รหัส

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

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


2
จะเกิดอะไรขึ้นเมื่อมีการเปลี่ยนแปลงของปัญญาอ่อนConst.PERIODเท่ากับ~? ไม่มีเหตุผลสำหรับตัวละครที่มีชื่อซ้ำซาก แต่เพิ่มการบำรุงรักษาและความซับซ้อนที่ไม่จำเป็นในสภาพแวดล้อมการเขียนโปรแกรมสมัยใหม่ คุณจะเขียนชุดการทดสอบหน่วยที่พูดโดยทั่วไปassert(Const.PERIOD == '.')หรือไม่?

3
@JarrodRoberson - นั่นจะดูดแน่ แต่คุณจะเจอปัญหามากถ้ามีคนเพิ่มค่าคงที่ Unicode ที่ดูเหมือนว่าเครื่องหมายจุลภาคแทนที่จะเป็นเครื่องหมายจุลภาคที่แท้จริง อย่างที่ฉันบอกไปนี่ไม่ใช่สิ่งที่ฉันทำในโครงการพัฒนาสีเขียว แต่ถ้าคุณมีรหัสฐานแบบดั้งเดิมที่มีชุดการทดสอบที่ไม่แน่นอนซึ่งคุณได้ทำเครื่องหมายจุลภาค / เครื่องหมายอัญประกาศ / เครื่องหมายอัญประกาศเดี่ยว / apostrophe / Microsoft สิ่งที่น่ารังเกียจของ Microsoft ออกมาสองสามครั้งการสร้างค่าคงที่และบอกให้คนใช้อาจเป็นวิธีที่สมเหตุสมผล รหัสดีขึ้นโดยไม่ต้องใช้การทดสอบการเขียนหนึ่งปี
Justin Cave

3
ตัวอย่างที่สืบทอดมาของคุณนั้นแย่มากฉันเพิ่งเสร็จสิ้นการสร้างฐานรหัส LOC อีก 1,000,000+ ที่มีอายุ 18 ปี มันมีตัวละครที่พิมพ์ได้ทุกตัวกำหนดเช่นนี้หลายครั้งด้วยชื่อที่ขัดแย้งกันแม้กระทั่ง และหลายสิ่งหลายครั้งชื่อที่ตั้งจริงCOMMA = SPACE + "," + SPACEใช่คนงี่เง่าบางคนมีSPACEค่าคงที่ ฉันปรับโครงสร้างใหม่ทั้งหมดและรหัสคือคำสั่งของ magitude ที่อ่านได้มากขึ้นและวิทยาลัยได้รับการว่าจ้างมากขึ้นสามารถติดตามสิ่งต่าง ๆ และแก้ไขได้โดยไม่ต้องมี 6 ระดับของการอ้อมเพื่อค้นหาสิ่งที่ตั้งค่าจริง ๆ

-1

ค่าคงที่แบบอักขระเดียวดีกว่าตัวอักษรจริงหรือไม่

มีความสับสนมากมายที่ลอยอยู่รอบ ๆ ที่นี่ ให้ฉันดูว่าฉันสามารถแซะพวกเขาแยกจากกัน

ค่าคงที่ให้:

  • อรรถศาสตร์
  • เปลี่ยนระหว่างการพัฒนา
  • ความร้าย

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

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

หากความหมายเชิงความหมายมีอยู่และเนื่องจากทั้งคู่เป็นค่าคงที่ดังนั้นค่าคงที่นั้นมีค่ามากกว่าตัวอักษรหรือไม่

การอ้อมทางอ้อมสามารถแก้ปัญหาใด ๆ ได้

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

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

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


1
ความหมายคือกุญแจ ถ้าและ "A" มีความหมายมากกว่าเพียงแค่เป็น "A" ดังนั้นมันก็คุ้มค่าที่จะผูกความหมายเดียวกันกับการอ้างอิง "เดียวกัน" ไม่สำคัญว่าจะเป็นค่าคงที่หรือไม่ ฉันเห็นด้วยอย่างยิ่ง
oopexpert

-1

ในฐานะที่เป็นข้อโต้แย้งเชิงปรัชญาต่อความเห็นส่วนใหญ่ฉันต้องระบุว่ามีพวกเราบางคนที่ชื่นชมโปรแกรมเมอร์ชาวนาฝรั่งเศสในศตวรรษที่ 19 ที่ไม่มีความซับซ้อนและ

จำได้ว่าเขาจำเจจำเจความว่างเปล่านิรันดร์ของเขามุมมองที่ชาญฉลาดของเขาทุกอย่างความพึงพอใจมหึมาของเขาด้วยความจริงอยู่เพียงเพราะพวกเขาเป็นจริง "ทำลายทุกอย่าง!" Turnbull ร้องไห้กับตัวเอง "ถ้าเขาอยู่ในโรงพยาบาลไม่มีใครอยู่ข้างนอก"

GK Chesterton, The Ball and The Cross

ไม่มีอะไรผิดชื่นชมความจริงและไม่มีอะไรผิดปกติในการระบุความจริงโดยเฉพาะเมื่อพูดคุยกับคอมพิวเตอร์

ถ้าคุณโกหกคอมพิวเตอร์มันจะทำให้คุณ

Perry Farrar - Germantown, Maryland (จากโปรแกรมเพิ่มเติมไข่มุก)


แต่ส่วนใหญ่ฉันเห็นด้วยกับคนที่พูดว่ามันโง่ ฉันยังเด็กเกินไปที่จะเรียนรู้ที่จะตั้งโปรแกรม FORTRAN แต่ฉันได้ยินมาว่าคุณสามารถกำหนดใหม่'A' = 'Q'และสร้าง cryptograms ที่ยอดเยี่ยมได้ทุกประเภท คุณไม่ได้ทำสิ่งนี้

นอกเหนือจากปัญหา i18n ที่เกิดขึ้นก่อนหน้านี้ (ซึ่งไม่ได้นิยามใหม่ของสัญลักษณ์ "COMMA" แต่แท้จริงแล้วนิยามใหม่ของสัญลักษณ์ของ DECIMAL_POINT) การสร้างคำพูด carroty ฝรั่งเศสหรือคำพูดเดียวของอังกฤษเพื่อสื่อความหมายกับมนุษย์นั้นเป็นเรื่องจริงและสิ่งเหล่านั้นควรจะเป็นตัวแปรไม่ใช่ค่าคงที่ ค่าคงที่จะเป็นAMERICAN_COMMA := ','และcomma := AMERICAN_COMMA

และถ้าฉันใช้รูปแบบตัวสร้างเพื่อสร้าง SQL Query ฉันจะเห็น

sb.append("insert into ")
 .append(table_name)
 .append(" values ")
 .append(" ( ")
 .append(val_1)
 .append(",")
 .append(val_2)
 .append(" ); ")

มากกว่าสิ่งอื่นใด แต่ถ้าคุณจะเพิ่มค่าคงที่ก็จะเป็น

INSERT_VALUES_START = " ( "
INSERT_VALUES_END = " ) "
INSERT_VALUES_SEPARATOR = " , "
QUERY_TERMINATOR = ";"

sb.append("insert into ")
 .append(table_name)
 .append(" values ")
 .append(INSERT_VALUES_START)
 .append(val_1)
 .append(INSERT_VALUES_SEPARATOR)
 .append(val_2)
 .append(INSERT_VALUES_END)
 .append(QUERY_TERMINATOR)

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

ไม่มีสิ่งใดที่จะเติมข้อความให้คุณโดยอัตโนมัติดังนั้นถ้าฉันได้เครื่องหมายจุลภาคโดยการกด 'con', alt-space, down, down, down, down, ป้อนและขอใบเสนอราคาโดยกด 'con', alt-space, down, ลงให้ใส่ ฉันอาจทำเช่นนั้น


สิ่งที่ต้องจำเกี่ยวกับตัวอักษรสตริงอีกวิธีคือพวกเขาจะรวบรวม อย่างน้อยใน Delphi (ซึ่งเป็นภาษาเดียวที่ฉันหมกมุ่นอยู่กับสแต็คของ) คุณจะไขตัวอักษรของคุณลงในสแต็กของแต่ละฟังก์ชั่น ดังนั้นตัวอักษรจำนวนมาก = ค่าใช้จ่ายของฟังก์ชันมาก "," ใน function_A ไม่ใช่หน่วยความจำบิตเดียวกับ "," ใน function_B "เพื่อต่อสู้กับสิ่งนี้มี" สตริงทรัพยากร "ซึ่งสามารถสร้างและเชื่อมโยงในด้านข้าง - และนี่คือวิธีที่พวกเขาทำสิ่งที่ i18n (ฆ่า นกสองตัวที่มีหนึ่งบุช) ใน Python ตัวอักษรสตริงทั้งหมดของคุณเป็นวัตถุและอาจใช้งานได้utils.constants.COMMA.join(["some","happy","array","strings"])ดี แต่มันไม่ใช่แนวคิดที่เด่นชัดสำหรับจุดซ้ำ ๆ ซ้ำ ๆ ในหน้านี้


-4

แต่เมื่อไหร่เราจะเริ่มใช้สัญลักษณ์ที่แตกต่างจาก ',' เพื่อเป็นตัวแทนของเครื่องหมายจุลภาค?

สำหรับการแปล

ในประเทศที่พูดภาษาอังกฤษสัญลักษณ์ที่แยกส่วนและส่วนของทศนิยมคือ "." ซึ่งเราเรียกว่า "จุดทศนิยม" ในหลาย ๆ ประเทศสัญลักษณ์คือ "," และโดยทั่วไปจะเรียกว่า "จุลภาค" ในภาษาท้องถิ่น ในทำนองเดียวกันที่ประเทศที่พูดภาษาอังกฤษใช้ "," เพื่อแยกกลุ่มของตัวเลขสามหลักในจำนวนมาก (เช่น 1,000,000 สำหรับหนึ่งล้าน) ประเทศที่ใช้เครื่องหมายจุลภาคเป็นจุดทศนิยมใช้จุด (1.000.000)

ดังนั้นจึงมีกรณีสำหรับการสร้างค่าคงที่ DECIMAL_POINT และ COMMA หากคุณกำลังทำโลกาภิวัตน์


2
แต่แล้ว COMMA และ DECIMAL_POINT ไม่ใช่ชื่อที่ถูกต้องสำหรับเอนทิตี (ซึ่งอาจเป็นสาเหตุที่คุณถูกลดระดับลง)
Kyle Strand

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