ใน C / C ++ ตัวแปรทั่วโลกไม่ดีเท่าที่อาจารย์คิด
ใน C / C ++ ตัวแปรทั่วโลกไม่ดีเท่าที่อาจารย์คิด
คำตอบ:
ปัญหาเกี่ยวกับตัวแปรโกลบอลคือเนื่องจากทุกฟังก์ชั่นสามารถเข้าถึงสิ่งเหล่านี้ได้มันจึงยากที่จะทราบว่าฟังก์ชั่นใดที่อ่านและเขียนตัวแปรเหล่านี้จริง
เพื่อให้เข้าใจถึงการทำงานของแอพพลิเคชั่นคุณต้องคำนึงถึงทุกฟังก์ชั่นที่ปรับเปลี่ยนสถานะของโลก สามารถทำได้ แต่เมื่อแอปพลิเคชันเติบโตขึ้นจะทำให้จุดที่เป็นไปไม่ได้ยากขึ้น (หรืออย่างน้อยก็สิ้นเปลืองเวลา)
หากคุณไม่พึ่งพาตัวแปรส่วนกลางคุณสามารถส่งผ่านสถานะระหว่างฟังก์ชั่นต่าง ๆ ได้ตามต้องการ ด้วยวิธีนี้คุณจะมีโอกาสที่ดีขึ้นในการทำความเข้าใจว่าแต่ละฟังก์ชั่นทำอะไรเพราะคุณไม่จำเป็นต้องคำนึงถึงสถานะโลก
สิ่งสำคัญคือการจำเป้าหมายโดยรวม: ความชัดเจน
กฎ "ไม่มีตัวแปรกลาง" อยู่ที่นั่นเพราะส่วนใหญ่แล้วตัวแปรกลางทำให้ความหมายของรหัสชัดเจนน้อยลง
อย่างไรก็ตามเช่นเดียวกับหลาย ๆ กฎผู้คนจำกฎได้และไม่ใช่กฎที่ตั้งใจจะทำ
ฉันได้เห็นโปรแกรมที่ดูเหมือนจะเพิ่มขนาดของรหัสสองเท่าด้วยการส่งพารามิเตอร์จำนวนมากรอบตัวเพื่อหลีกเลี่ยงความชั่วร้ายของตัวแปรทั่วโลก ในท้ายที่สุดการใช้ globals จะทำให้โปรแกรมนั้นชัดเจนยิ่งขึ้นสำหรับผู้อ่าน ด้วยการยึดมั่นในคำของกฎอย่างไม่มีเหตุผลโปรแกรมเมอร์ดั้งเดิมจึงล้มเหลวในความตั้งใจของกฎ
ดังนั้นใช่, กลมมักจะไม่ดี แต่ถ้าคุณรู้สึกว่าในท้ายที่สุดเจตนาของโปรแกรมเมอร์นั้นชัดเจนขึ้นโดยการใช้ตัวแปรทั่วโลกจากนั้นไปข้างหน้า อย่างไรก็ตามโปรดจำไว้ว่าการลดลงของความคมชัดที่เกิดขึ้นโดยอัตโนมัติเมื่อคุณบังคับให้ใครบางคนเข้าถึงโค้ดชิ้นที่สอง (กลม) เพื่อทำความเข้าใจว่าชิ้นแรกทำงานอย่างไร
อาจารย์ของฉันเคยพูดบางอย่างเช่น: การใช้ตัวแปรทั่วโลกจะไม่เป็นไรถ้าคุณใช้อย่างถูกต้อง ฉันคิดว่าฉันใช้มันไม่ถูกต้องฉันจึงไม่ค่อยใช้มันเลย
static
ตัวแปรทั่วโลกเป็นจำนวนมากภาษาคือ C. เมื่อถูก จำกัด อยู่ในหน่วยการแปลที่ค่อนข้างเล็กพวกเขาเริ่มคล้ายกับตัวแปรคลาสของวัตถุ C ++
program lifetime, file scope variables
. และพวกเขากลายเป็นระดับโลกเลยทีเดียวเมื่อคุณผ่านตัวชี้ไปยังตัวแปรกับโลกภายนอก (ซึ่งเป็นไปไม่ได้กับตัวแปรอัตโนมัติ) ..
static
ตัวแปรทั่วโลกมีขอบเขต จำกัด ในหน่วยการแปลเดียวกัน แต่พวกเขามีอายุการใช้งานจนถึงสิ้นสุดโปรแกรมเป็นตัวแปรทั่วโลก
ตัวแปรโกลบอลควรใช้เมื่อคุณไม่มีทางเลือกอื่น และใช่แล้วรวมถึงซิงเกิลตันด้วย 90% ของเวลานั้นมีการแนะนำตัวแปรส่วนกลางเพื่อประหยัดค่าใช้จ่ายในการผ่านพารามิเตอร์ จากนั้นการทดสอบมัลติเธรด / หน่วยการทดสอบ / การบำรุงรักษาเกิดขึ้นและคุณมีปัญหา
ใช่ใน 90% ของสถานการณ์ทั่วโลกตัวแปรไม่ดี คุณไม่เห็นข้อยกเว้นในปีการศึกษาของคุณ ข้อยกเว้นหนึ่งที่ฉันสามารถคิดได้จากส่วนบนของหัวของฉันคือการจัดการกับวัตถุทั่วโลกโดยเนื้อแท้เช่นตารางขัดจังหวะ สิ่งต่าง ๆ เช่นการเชื่อมต่อฐานข้อมูลดูเหมือนจะเป็นของโลก แต่ไม่ใช่
ปัญหาที่ตัวแปรโกลบอลสร้างขึ้นสำหรับโปรแกรมเมอร์คือมันขยายพื้นผิวการเชื่อมต่อระหว่างส่วนประกอบระหว่างส่วนประกอบต่างๆที่ใช้ตัวแปรทั่วโลก สิ่งนี้หมายความว่าเมื่อจำนวนส่วนประกอบที่ใช้ตัวแปรทั่วโลกเพิ่มขึ้นความซับซ้อนของการโต้ตอบก็เพิ่มขึ้นเช่นกัน การมีเพศสัมพันธ์ที่เพิ่มขึ้นนี้มักจะทำให้ข้อบกพร่องง่ายต่อการฉีดเข้าสู่ระบบเมื่อทำการเปลี่ยนแปลงและทำให้ข้อบกพร่องยากต่อการวินิจฉัยและแก้ไข การมีเพศสัมพันธ์เพิ่มขึ้นนี้ยังสามารถลดจำนวนของตัวเลือกที่มีเมื่อทำการเปลี่ยนแปลงและสามารถเพิ่มความพยายามที่จำเป็นสำหรับการเปลี่ยนแปลงบ่อยครั้งที่ต้องติดตามผ่านโมดูลต่าง ๆ ที่ยังใช้ตัวแปรทั่วโลกเพื่อกำหนดผลที่ตามมาของการเปลี่ยนแปลง
จุดประสงค์ของการห่อหุ้มซึ่งตรงข้ามกับการใช้ตัวแปรทั่วโลกคือการลดการเชื่อมต่อเพื่อให้เข้าใจและเปลี่ยนแหล่งที่มาได้ง่ายขึ้นปลอดภัยขึ้นและทดสอบได้ง่ายขึ้น มันง่ายกว่ามากที่จะใช้การทดสอบหน่วยเมื่อไม่ได้ใช้ตัวแปรส่วนกลาง
ตัวอย่างเช่นหากคุณมีตัวแปรจำนวนเต็มแบบง่ายทั่วโลกที่ใช้เป็นตัวบ่งชี้ที่ระบุว่าส่วนประกอบต่าง ๆ ใช้เป็นเครื่องสถานะและจากนั้นคุณทำการเปลี่ยนแปลงโดยการเพิ่มสถานะใหม่สำหรับส่วนประกอบใหม่คุณต้องติดตามผ่านส่วนอื่น ๆ ทั้งหมด ส่วนประกอบเพื่อให้แน่ใจว่าการเปลี่ยนแปลงจะไม่ส่งผลกระทบต่อพวกเขา ตัวอย่างของปัญหาที่เป็นไปได้คือถ้าswitch
คำสั่งทดสอบค่าของตัวแปรโกลบอลการแจงนับกับcase
คำสั่งสำหรับแต่ละค่าปัจจุบันจะถูกใช้ในสถานที่ต่าง ๆ และมันเกิดขึ้นว่าบางswitch
คำสั่งไม่มีdefault
กรณีที่จะจัดการ คุณค่าที่ไม่คาดคิดสำหรับโลกในทันใดคุณมีพฤติกรรมที่ไม่ได้กำหนดไว้ตราบใดที่แอปพลิเคชันเกี่ยวข้อง
ในทางกลับกันการใช้พื้นที่ข้อมูลที่ใช้ร่วมกันอาจถูกนำมาใช้เพื่อให้มีชุดของพารามิเตอร์ทั่วโลกซึ่งมีการอ้างอิงตลอดทั้งใบสมัคร วิธีนี้มักใช้กับแอพพลิเคชั่นที่ฝังตัวพร้อมกับหน่วยความจำขนาดเล็ก
เมื่อใช้ตัวแปรโกลบอลในแอพพลิเคชั่นประเภทนี้โดยทั่วไปความรับผิดชอบในการเขียนไปยังพื้นที่ข้อมูลจะถูกจัดสรรให้กับองค์ประกอบเดียวและส่วนประกอบอื่น ๆ ทั้งหมดจะเห็นพื้นที่เป็นconst
และอ่านจากมันไม่ควรเขียนลงไป การใช้วิธีการนี้จะ จำกัด ปัญหาที่สามารถพัฒนาได้
ปัญหาเล็กน้อยจากตัวแปรทั่วโลกที่ต้องแก้ไข
เมื่อแหล่งที่มาสำหรับตัวแปรส่วนกลางเช่น struct ถูกปรับเปลี่ยนทุกอย่างที่ใช้จะต้องถูกคอมไพล์ใหม่เพื่อให้ทุกอย่างที่ใช้ตัวแปรรู้ขนาดที่แท้จริงและเทมเพลตหน่วยความจำ
หากมีมากกว่าหนึ่งองค์ประกอบที่สามารถแก้ไขตัวแปรโกลบอลได้คุณสามารถพบปัญหากับข้อมูลที่ไม่คงที่ซึ่งอยู่ในตัวแปรโกลบอล ด้วยแอพพลิเคชั่นแบบมัลติเธรดคุณอาจจะต้องเพิ่มการล็อกหรือส่วนที่สำคัญบางอย่างเพื่อให้วิธีการเพื่อให้มีเพียงหนึ่งเธรดในแต่ละครั้งที่สามารถแก้ไขตัวแปรโกลบอลและเมื่อเธรดกำลังแก้ไขตัวแปรการเปลี่ยนแปลงทั้งหมดเสร็จสมบูรณ์ และกระทำก่อนที่เธรดอื่นจะสามารถสืบค้นตัวแปรหรือแก้ไขมันได้
การดีบักแอ็พพลิเคชันแบบมัลติเธรดที่ใช้ตัวแปรโกลบอลอาจยากกว่า คุณสามารถเรียกใช้ในสภาพการแข่งขันที่สามารถสร้างข้อบกพร่องที่ยากที่จะทำซ้ำ ด้วยองค์ประกอบหลายอย่างที่สื่อสารกันผ่านตัวแปรทั่วโลกโดยเฉพาะอย่างยิ่งในแอพพลิเคชั่นแบบมัลติเธรดทำให้สามารถรู้ได้ว่าองค์ประกอบใดบ้างที่เปลี่ยนแปลงตัวแปรเวลาและวิธีการเปลี่ยนแปลงตัวแปรนั้นยากที่จะเข้าใจ
การปะทะกันของชื่ออาจมีปัญหากับการใช้ตัวแปรโกลบอล ตัวแปรโลคัลที่มีชื่อเหมือนกับตัวแปรโกลบอลสามารถซ่อนตัวแปรโกลบอล นอกจากนี้คุณยังพบปัญหาการตั้งชื่อเมื่อใช้ภาษาการเขียนโปรแกรม C การหลีกเลี่ยงคือการแบ่งระบบออกเป็นระบบย่อยด้วยตัวแปรส่วนกลางสำหรับระบบย่อยเฉพาะโดยเริ่มต้นด้วยตัวอักษรสามตัวแรกที่เหมือนกันทั้งหมด (ดูที่การแก้ไขปัญหาการชนกันของชื่อพื้นที่ในวัตถุประสงค์ C ) C ++ ให้เนมสเปซและด้วย C คุณสามารถหลีกเลี่ยงสิ่งนี้ได้โดยการสร้างโครงสร้างที่มองเห็นได้ทั่วโลกซึ่งสมาชิกเป็นไอเท็มข้อมูลและพอยน์เตอร์ที่หลากหลายให้กับข้อมูลและฟังก์ชั่นที่ให้ไว้ในไฟล์ โครงสร้างที่มองเห็นได้ทั่วโลก
ในบางกรณีเจตนาของแอ็พพลิเคชันดั้งเดิมจะถูกเปลี่ยนเพื่อให้ตัวแปรโกลบอลที่จัดเตรียมสถานะสำหรับเธรดเดี่ยวถูกแก้ไขเพื่ออนุญาตเธรดที่ซ้ำกันหลายตัวให้รัน ตัวอย่างจะเป็นแอปพลิเคชันแบบง่ายที่ออกแบบมาสำหรับผู้ใช้รายเดียวโดยใช้ตัวแปรส่วนกลางสำหรับสถานะจากนั้นคำขอจะมาจากการจัดการเพื่อเพิ่มส่วนต่อประสาน RESTเพื่อให้แอปพลิเคชันระยะไกลทำหน้าที่เสมือนผู้ใช้ ดังนั้นตอนนี้คุณต้องมีการทำซ้ำตัวแปรทั่วโลกและข้อมูลสถานะของพวกเขาเพื่อให้ผู้ใช้คนเดียวเช่นเดียวกับผู้ใช้เสมือนจากแอปพลิเคชันระยะไกลแต่ละคนมีชุดของตัวแปรระดับโลกที่เป็นเอกลักษณ์
ใช้ C ++ namespace
และstruct
เทคนิคสำหรับ C
สำหรับภาษาการเขียนโปรแกรม C ++ namespace
คำสั่งจะช่วยได้มากในการลดโอกาสในการปะทะกันของชื่อ namespace
พร้อมกับclass
และคำหลักการเข้าถึงที่หลากหลาย ( private
, protected
และpublic
) มอบเครื่องมือส่วนใหญ่ที่คุณต้องการเพื่อแค็ปซูลตัวแปร อย่างไรก็ตามภาษาการเขียนโปรแกรม C ไม่ได้มีคำสั่งนี้ การโพสต์สแต็คโฟลว์โฟลว์เนมสเปซใน Cมีเทคนิคบางอย่างสำหรับ C
เทคนิคที่มีประโยชน์คือการมีพื้นที่ข้อมูลหน่วยความจำเดียวที่ถูกกำหนดให้เป็นstruct
ที่มีการมองเห็นทั่วโลกและภายในนี้struct
เป็นตัวชี้ไปยังตัวแปรทั่วโลกและฟังก์ชั่นที่จะถูกเปิดเผย คำจำกัดความที่แท้จริงของตัวแปรโกลบอลกำหนดขอบเขตไฟล์โดยใช้static
คีย์เวิร์ด หากคุณใช้const
คำหลักเพื่อระบุว่าเป็นแบบอ่านอย่างเดียวคอมไพเลอร์สามารถช่วยคุณในการบังคับใช้การเข้าถึงแบบอ่านอย่างเดียว
การใช้struct
เทคนิคยังสามารถห่อหุ้มโลกเพื่อที่จะกลายเป็นแพคเกจหรือส่วนประกอบที่เกิดขึ้นเป็นโลก โดยการมีส่วนประกอบประเภทนี้มันจะง่ายต่อการจัดการการเปลี่ยนแปลงที่มีผลต่อโลกและฟังก์ชั่นการใช้งานทั่วโลก
อย่างไรก็ตามในขณะที่namespace
หรือstruct
เทคนิคสามารถช่วยจัดการการปะทะกันของชื่อปัญหาพื้นฐานของการมีเพศสัมพันธ์ระหว่างองค์ประกอบที่การใช้งานของ globals แนะนำโดยเฉพาะอย่างยิ่งในการประยุกต์ใช้แบบมัลติเธรดที่ทันสมัยยังคงมีอยู่
ใช่ แต่คุณไม่ต้องเสียค่าใช้จ่ายของตัวแปรทั่วโลกจนกว่าคุณจะหยุดทำงานในรหัสที่ใช้ตัวแปรทั่วโลกและเริ่มเขียนอย่างอื่นที่ใช้รหัสที่ใช้ตัวแปรทั่วโลก แต่ราคายังอยู่ที่นั่น
มันเป็นค่าใช้จ่ายทางอ้อมระยะยาวและคนส่วนใหญ่คิดว่ามันไม่เลว
หากเป็นไปได้รหัสของคุณจะสิ้นสุดลงภายใต้การพิจารณาอย่างละเอียดในระหว่างการพิจารณาคดีของศาลฎีกาคุณต้องการให้แน่ใจว่าจะหลีกเลี่ยงตัวแปรส่วนกลาง
ดูบทความนี้: รหัส Buggy breathalyzer สะท้อนให้เห็นถึงความสำคัญของการตรวจสอบแหล่งที่มา
มีปัญหาบางอย่างกับรูปแบบของรหัสที่ถูกระบุโดยการศึกษาทั้งคู่ หนึ่งในประเด็นที่เกี่ยวข้องโวหารแสดงความคิดเห็นเป็นคนใช้ที่กว้างขวางของตัวแปรทั่วโลกที่ไม่มีการป้องกัน นี่ถือเป็นรูปแบบที่ไม่ดีเพราะมันจะเพิ่มความเสี่ยงที่สถานะของโปรแกรมจะไม่สอดคล้องกันหรือค่านั้นจะถูกแก้ไขหรือเขียนทับโดยไม่ตั้งใจ นักวิจัยยังแสดงความกังวลเกี่ยวกับความจริงที่ว่าความแม่นยำเลขทศนิยมนั้นไม่ได้รับการบำรุงรักษาอย่างสม่ำเสมอตลอดทั้งรหัส
ชายฉันคิดว่านักพัฒนาเหล่านั้นต้องการที่จะไม่ใช้ตัวแปรทั่วโลก
ตัวแปรทั่วโลกไม่ดีเท่าที่คุณทำไม่น้อยกว่า
หากคุณกำลังสร้างโปรแกรม encapsulated อย่างสมบูรณ์คุณสามารถใช้ globals มันเป็น "บาป" ที่จะใช้กลม แต่การเขียนโปรแกรมบาปเป็นปรัชญาอย่างหนัก
หากคุณตรวจสอบL.in.oleumคุณจะเห็นภาษาที่มีตัวแปรเป็นระดับโลกเพียงอย่างเดียว มันไม่สามารถปรับขนาดได้เพราะห้องสมุดทุกแห่งไม่มีทางเลือกนอกจากใช้ globals
ที่กล่าวว่าหากคุณมีทางเลือกและสามารถเพิกเฉยต่อปรัชญาของโปรแกรมโปรแกรมเมอร์ผู้คนก็ไม่ได้แย่ขนาดนั้น
ไม่ใช่ทั้ง Gotos ถ้าคุณใช้ถูกต้อง
ปัญหาใหญ่ "เลวร้าย" ก็คือถ้าคุณใช้มันผิดคนกรีดร้องผู้ก่อกวนดาวอังคารตกและโลกก็ระเบิดขึ้น .... หรืออะไรทำนองนั้น
ฉันจะตอบคำถามนี้ด้วยคำถามอื่น: คุณใช้singeltons / singeltons ไม่ดีหรือไม่?
เพราะการใช้งาน singelton (เกือบทั้งหมด) เป็นตัวแปรทั่วโลกที่ได้รับเกียรติ
ปัญหาคือน้อยกว่าที่พวกเขากำลังเลวร้ายและอื่น ๆ ว่าพวกเขากำลังอันตราย พวกเขามีชุดของข้อดีและข้อเสียของตัวเองและมีสถานการณ์ที่พวกเขาทั้งสองมีประสิทธิภาพมากที่สุดหรือวิธีเดียวที่จะบรรลุงานเฉพาะ อย่างไรก็ตามมันง่ายมากที่จะใช้งานในทางที่ผิดแม้ว่าคุณจะทำตามขั้นตอนเพื่อใช้งานอย่างถูกต้องก็ตาม
ข้อดีไม่กี่:
ข้อเสียไม่กี่:
โปรดทราบว่าถ้าคุณจะเห็นว่าข้อดีสองข้อแรกและข้อเสียสองข้อแรกที่ฉันระบุไว้นั้นเป็นสิ่งเดียวกันโดยใช้ถ้อยคำที่แตกต่างกัน นี่เป็นเพราะคุณสมบัติของตัวแปรทั่วโลกนั้นมีประโยชน์จริง ๆ แต่คุณสมบัติที่ทำให้พวกเขามีประโยชน์นั้นเป็นสาเหตุของปัญหาทั้งหมด
แนวทางแก้ไขที่เป็นไปได้สำหรับปัญหาบางประการ:
Globals
หรือGlobalVars
) หรือใช้หลักการตั้งชื่อมาตรฐานสำหรับตัวแปรทั่วโลก (เช่นglobal_[name]
หรือg_module_varNameStyle
(ดังที่กล่าวถึงโดย underscore_d ในความคิดเห็น )) ทั้งสองนี้จะบันทึกการใช้งานของพวกเขา (คุณสามารถค้นหารหัสที่ใช้ตัวแปรส่วนกลางโดยค้นหาชื่อ namespace / struct) และลดผลกระทบต่อเนมสเปซส่วนกลางextern
ในส่วนหัวที่เกี่ยวข้องดังนั้นการใช้งานจะถูก จำกัด ไว้ที่หน่วยการคอมไพล์ที่จำเป็นต้องเข้าถึง หากรหัสของคุณขึ้นอยู่กับตัวแปรส่วนกลางจำนวนมาก แต่หน่วยการคอมไพล์แต่ละหน่วยต้องการการเข้าถึงเพียงเล็กน้อยเท่านั้นคุณสามารถพิจารณาจัดเรียงไฟล์เหล่านั้นเป็นไฟล์ต้นฉบับได้หลายไฟล์ดังนั้นจึงง่ายกว่าที่จะ จำกัด การเข้าถึงตัวแปรโกลบอลแต่ละไฟล์ไม่ว่ามันจะดีหรือไม่ดีก็ขึ้นอยู่กับว่าคุณใช้มันอย่างไร คนส่วนใหญ่มีแนวโน้มที่จะใช้พวกเขาไม่ดีดังนั้นความวุ่นวายทั่วไปที่มีต่อพวกเขา หากใช้อย่างถูกต้องพวกเขาสามารถเป็นประโยชน์ใหญ่; หากใช้ไม่ดีพวกเขาสามารถและจะกลับมากัดคุณได้ทุกเมื่อและวิธีที่คุณคาดหวังน้อยที่สุด
วิธีที่ดีในการดูคือพวกเขาเองนั้นไม่ได้เลวร้าย แต่พวกเขาเปิดใช้งานการออกแบบที่ไม่ดีและสามารถเพิ่มเอฟเฟกต์ของการออกแบบที่ไม่ดีได้ทวีคูณ
แม้ว่าคุณจะไม่ต้องการใช้มันก็เป็นการดีกว่าที่จะรู้วิธีใช้อย่างปลอดภัยและเลือกที่จะไม่ใช้ไม่ใช่เพราะคุณไม่ทราบวิธีใช้อย่างปลอดภัย หากคุณเคยพบว่าตัวเองอยู่ในสถานการณ์ที่คุณจำเป็นต้องบำรุงรักษาโค้ดที่มีอยู่แล้วซึ่งอาศัยตัวแปรทั่วโลกคุณอาจประสบปัญหาหากคุณไม่รู้วิธีใช้งานอย่างถูกต้อง
g_module_varNameStyle
อ่านง่ายอย่างสมบูรณ์ เพื่อความชัดเจนฉันไม่ได้ใช้ globals ถ้าฉันสามารถหลีกเลี่ยงได้ง่าย - คำสำคัญได้อย่างง่ายดายเพราะเมื่อฉันหยุดเชื่อว่าพวกเขาจะต้องหลีกเลี่ยง - หรือค่อนข้างงง - ค่าใช้จ่ายทั้งหมดฉันมีเวลาที่ดีขึ้นมาก & รหัส is (shock!) far tidier
ดังที่มีคนพูดว่า (ฉันถอดความ) ในหัวข้ออื่น "กฎเช่นนี้ไม่ควรเสียจนกว่าคุณจะเข้าใจผลของการทำเช่นนั้น"
มีหลายครั้งที่จำเป็นต้องใช้ตัวแปรทั่วโลกหรืออย่างน้อยก็มีประโยชน์มาก (ตัวอย่างเช่นการทำงานกับการโทรกลับที่กำหนดโดยระบบ) ในทางกลับกันพวกเขาก็อันตรายเช่นกันด้วยเหตุผลทั้งหมดที่คุณได้รับการบอกกล่าว
มีหลายแง่มุมของการเขียนโปรแกรมที่น่าจะถูกทิ้งไว้กับผู้เชี่ยวชาญ บางครั้งคุณต้องมีดที่คมมาก แต่คุณจะไม่ได้ใช้จนกว่าคุณจะพร้อม ...
โดยทั่วไปแล้วตัวแปรทั่วโลกจะไม่ดีโดยเฉพาะอย่างยิ่งหากคนอื่นกำลังทำงานกับรหัสเดียวกันและไม่ต้องการใช้เวลา 20 นาทีในการค้นหาสถานที่ทั้งหมดที่มีการอ้างอิงตัวแปร และการเพิ่มเธรดที่ปรับเปลี่ยนตัวแปรจะทำให้เกิดอาการปวดหัวในระดับใหม่ทั้งหมด
ค่าคงที่ส่วนกลางในเนมสเปซที่ไม่ระบุชื่อที่ใช้ในหน่วยการแปลเดียวนั้นใช้ได้ดีและแพร่หลายในแอพและห้องสมุดมืออาชีพ แต่ถ้าข้อมูลไม่แน่นอนและ / หรือต้องมีการแชร์ระหว่าง TU หลายตัวคุณอาจต้องการแค็ปซูล - หากไม่ใช่เพื่อประโยชน์ในการออกแบบดังนั้นเพื่อการดีบักหรือทำงานกับโค้ดของคุณ
การใช้ตัวแปรทั่วโลกนั้นเหมือนกับการกวาดสิ่งสกปรกใต้พรม เป็นการแก้ไขอย่างรวดเร็วและง่ายกว่ามากในระยะสั้นกว่าการเอาฝุ่นหรือฝุ่นไปทำความสะอาด อย่างไรก็ตามหากคุณเคยขยับพรมในภายหลังคุณจะมีความประหลาดใจใหญ่อยู่ด้านล่าง
ตัวแปรทั่วโลกไม่ดีถ้าพวกเขาอนุญาตให้คุณจัดการกับแง่มุมต่าง ๆ ของโปรแกรมที่ควรจะแก้ไขเฉพาะที่ ใน OOP globals มักขัดแย้งกับแนวคิด encapsulation
ฉันคิดว่าอาจารย์ของคุณกำลังพยายามที่จะหยุดนิสัยที่ไม่ดีก่อนที่มันจะเริ่ม
ตัวแปรทั่วโลกมีสถานที่ของพวกเขาและเช่นเดียวกับที่หลายคนบอกว่าการรู้ว่าที่ไหนและเมื่อไหร่ที่จะใช้พวกเขานั้นอาจซับซ้อน ดังนั้นฉันจึงคิดว่าแทนที่จะเข้าไปสู่ความกล้าหาญของสาเหตุว่าอย่างไรอย่างไรเมื่อใดและที่ไหนที่ตัวแปรระดับโลกที่อาจารย์ของคุณตัดสินใจจะสั่งห้าม ใครจะรู้เขาอาจยกเลิกการแบนพวกเขาในอนาคต
ไม่ได้อย่างแน่นอน. ในทางที่ผิดแม้ว่า ... ที่ไม่ดี
การถอดมันออกอย่างไม่สนใจเพื่อประโยชน์ของมันก็คือ ... ไม่สนใจ หากคุณไม่ทราบข้อดีและข้อเสียควรหลีกเลี่ยงและทำตามที่คุณได้รับการสอน / เรียนรู้ แต่ไม่มีอะไรผิดปกติกับตัวแปรทั่วโลก เมื่อคุณเข้าใจข้อดีข้อเสียดีกว่าให้ตัดสินใจด้วยตัวเอง
ตัวแปรทั่วโลกใช้ได้ในโปรแกรมขนาดเล็ก แต่น่ากลัวหากใช้แบบเดียวกันกับตัวใหญ่
ซึ่งหมายความว่าคุณสามารถใช้มันในขณะที่เรียนรู้ได้อย่างง่ายดาย นี่คือสิ่งที่อาจารย์ของคุณพยายามปกป้องคุณ
เมื่อคุณมีประสบการณ์มากขึ้นมันจะง่ายต่อการเรียนรู้เมื่อพวกเขาไม่เป็นไร
ไม่พวกเขาไม่เลวเลย คุณต้องดูรหัส (machine) ที่คอมไพเลอร์สร้างขึ้นเพื่อทำการตัดสินใจนี้บางครั้งมันก็ยิ่งแย่กว่าที่จะใช้ local มากกว่า global โปรดทราบด้วยว่าการวาง "สแตติก" ลงในตัวแปรท้องถิ่นนั้นทำให้มันเป็นโลก (และสร้างปัญหาที่น่าเกลียดอื่น ๆ ที่โลกที่แท้จริงจะแก้ไข) "globals ท้องถิ่น" ไม่ดีโดยเฉพาะอย่างยิ่ง
Globals ช่วยให้คุณควบคุมการใช้งานหน่วยความจำได้อย่างดีเช่นกันมีบางอย่างที่ทำได้ยากกว่าสำหรับคนในท้องถิ่น ทุกวันนี้มีความสำคัญในสภาพแวดล้อมแบบฝังตัวที่หน่วยความจำค่อนข้าง จำกัด สิ่งที่ต้องรู้ก่อนที่คุณจะถือว่าการฝังตัวนั้นเหมือนกับสภาพแวดล้อมอื่นและถือว่ากฎการเขียนโปรแกรมเหมือนกันทั่วทั้งกระดาน
มันเป็นการดีที่คุณตั้งคำถามเกี่ยวกับกฎที่สอนส่วนใหญ่ไม่ใช่เหตุผลที่คุณได้รับการบอกกล่าว บทเรียนที่สำคัญที่สุดไม่ใช่ว่านี่เป็นกฎที่จะติดตัวคุณไปตลอดกาล แต่นี่เป็นกฎที่ต้องให้เกียรติเพื่อที่จะผ่านชั้นเรียนนี้และก้าวไปข้างหน้า ในชีวิตคุณจะพบว่าสำหรับ บริษัท XYZ คุณจะมีกฎการเขียนโปรแกรมอื่น ๆ ที่คุณจะต้องให้เกียรติเพื่อให้ได้รับเงินเดือน ในทั้งสองสถานการณ์คุณสามารถโต้แย้งกฎได้ แต่ฉันคิดว่าคุณจะโชคดีกว่างานที่โรงเรียน คุณเป็นอีกหนึ่งนักเรียนหลายคนที่นั่งของคุณจะถูกแทนที่เร็ว ๆ นี้อาจารย์จะไม่เคยทำงานที่คุณเป็นหนึ่งในทีมเล็ก ๆ ของผู้เล่นที่ต้องดูผลิตภัณฑ์นี้ถึงจุดสิ้นสุดและในสภาพแวดล้อมที่มีการพัฒนากฎสำหรับ ประโยชน์ของสมาชิกในทีมตลอดจนผลิตภัณฑ์และ บริษัท ดังนั้นหากทุกคนมีความคิดเหมือนกันหรือสำหรับผลิตภัณฑ์โดยเฉพาะมีเหตุผลทางวิศวกรรมที่ดีที่จะละเมิดสิ่งที่คุณเรียนรู้ในวิทยาลัยหรือหนังสือบางเล่มเกี่ยวกับการเขียนโปรแกรมทั่วไปแล้วขายความคิดของคุณให้กับทีมงานและเขียนลงเป็นวิธีการที่เหมาะสม . ทุกอย่างเป็นเกมที่ยุติธรรมในโลกแห่งความจริง
หากคุณปฏิบัติตามกฎการเขียนโปรแกรมทั้งหมดที่สอนให้คุณในโรงเรียนหรือหนังสืออาชีพการเขียนโปรแกรมของคุณจะถูก จำกัด อย่างมาก คุณสามารถอยู่รอดและมีอาชีพการงานที่มีผล แต่ความกว้างและความกว้างของสภาพแวดล้อมที่มีให้คุณจะถูก จำกัด อย่างมาก ถ้าคุณรู้ว่าทำไมและกฎอยู่ที่นั่นและสามารถปกป้องมันได้ดีถ้าคุณมีเหตุผลเพียงอย่างเดียวคือ "เพราะครูของฉันพูดอย่างนั้น" ก็ไม่ดี
โปรดทราบว่าหัวข้อเช่นนี้มักจะเป็นที่ถกเถียงกันอยู่ในที่ทำงานและจะยังคงดำเนินต่อไปในขณะที่คอมไพเลอร์และตัวประมวลผล (และภาษา) มีวิวัฒนาการเช่นเดียวกันกับกฎเหล่านี้และไม่มีการป้องกันตำแหน่งของคุณ ก้าวไปข้างหน้า.
ในเวลานั้นให้ทำอะไรก็ตามที่พูดเสียงดังหรือถือไม้เท้าที่ใหญ่ที่สุดพูด (จนกว่าจะถึงเวลาที่คุณเป็นคนดังตะโกนเสียงดังและถือไม้ที่ใหญ่ที่สุด)
ฉันต้องการที่จะโต้แย้งกับจุดที่ถูกสร้างขึ้นในหัวข้อนี้ว่ามันทำให้หลายเธรดหนักขึ้นหรือเป็นไปไม่ได้ต่อ se ตัวแปรทั่วโลกเป็นสถานะที่ใช้ร่วมกัน แต่ทางเลือกในการกลม (เช่นผ่านตัวชี้ไปรอบ ๆ ) อาจแบ่งรัฐ ปัญหาเกี่ยวกับมัลติเธรดคือวิธีการใช้สถานะที่แชร์อย่างถูกต้องไม่ว่าสถานะนั้นจะถูกแชร์ผ่านตัวแปรส่วนกลางหรืออย่างอื่น
ส่วนใหญ่เวลาที่คุณทำหลายเธรดคุณต้องแชร์บางสิ่ง ในรูปแบบโปรดิวเซอร์แบบผู้บริโภคคุณอาจแชร์คิวแบบเซฟเธรดบางอย่างที่มีหน่วยงาน และคุณได้รับอนุญาตให้แบ่งปันเพราะโครงสร้างข้อมูลนั้นปลอดภัยต่อเธรด ไม่ว่าคิวนั้นจะเป็นโกลบอลหรือไม่นั้นไม่เกี่ยวข้องอย่างสมบูรณ์เมื่อพูดถึงเรื่องความปลอดภัยของเธรด
ความหวังโดยนัยที่แสดงออกตลอดเธรดนี้ที่เปลี่ยนโปรแกรมจากเธรดเดี่ยวเป็นมัลติเธรดจะง่ายขึ้นเมื่อไม่ได้ใช้ globals ไร้เดียงสา ใช่วงกลมทำให้การยิงตัวเองง่ายขึ้น แต่มีหลายวิธีในการยิงตัวเอง
ฉันไม่ได้เรียกร้อง globals ในขณะที่จุดอื่น ๆ ยังคงอยู่จุดของฉันเป็นเพียงว่าจำนวนกระทู้ในโปรแกรมไม่มีอะไรเกี่ยวข้องกับขอบเขตของตัวแปร
ใช่เพราะถ้าคุณปล่อยให้โปรแกรมเมอร์ที่ไร้ความสามารถใช้มัน (อ่าน 90% โดยเฉพาะนักวิทยาศาสตร์) คุณจบลงด้วยตัวแปรทั่วโลก 600+ ไฟล์มากกว่า 20+ ไฟล์และโครงการ 12,000 บรรทัดที่ 80% ของฟังก์ชั่นเป็นโมฆะส่งคืนโมฆะและใช้งาน ทั้งหมดในรัฐโลก
มันเป็นไปไม่ได้อย่างรวดเร็วที่จะเข้าใจสิ่งที่เกิดขึ้น ณ จุดใดจุดหนึ่งเว้นแต่คุณจะรู้ว่าโครงการทั้งหมด
การใช้ตัวแปร Globalนั้นขึ้นอยู่กับข้อกำหนด ข้อดีของมันคือช่วยลดค่าใช้จ่ายในการส่งผ่านค่าซ้ำ ๆ
แต่อาจารย์ของคุณพูดถูกเพราะจะทำให้เกิดปัญหาด้านความปลอดภัยดังนั้นควรหลีกเลี่ยงการใช้ตัวแปรทั่วโลกให้มากที่สุด ตัวแปรทั่วโลกยังสร้างปัญหาที่บางครั้งก็เป็น เรื่องยากที่จะแก้ปัญหา
ตัวอย่างเช่น:-
สถานการณ์เมื่อค่าตัวแปรที่จะได้รับการแก้ไขในรันไทม์ ในขณะนั้นมันยากที่จะระบุว่าส่วนใดของรหัสที่แก้ไขและเงื่อนไขอะไร
ทั่วโลกเป็นสิ่งที่ดีเมื่อมันมาถึงการกำหนดค่า เมื่อเราต้องการเรากำหนดค่า / การเปลี่ยนแปลงที่จะมีผลกระทบต่อโลกในโครงการทั้งหมด
ดังนั้นเราจึงสามารถเปลี่ยนการตั้งค่าหนึ่งและการเปลี่ยนแปลงจะนำไปโครงการทั้งหมด แต่ฉันต้องเตือนคุณจะต้องฉลาดมากที่จะใช้ globals
ไม่ช้าก็เร็วคุณจะต้องเปลี่ยนวิธีการตั้งค่าตัวแปรหรือสิ่งที่จะเกิดขึ้นเมื่อมีการเข้าถึงหรือคุณเพียงแค่ต้องค้นหาตำแหน่งที่เปลี่ยนแปลง
มันจะดีกว่าเสมอหากไม่มีตัวแปรทั่วโลก เพียงแค่เขียนเขื่อนรับและตั้งค่าวิธีการและเป็นต่อมคุณเมื่อคุณต้องการพวกเขาในวันสัปดาห์หรือเดือนต่อมา
ฉันมักจะใช้ globals สำหรับค่าที่ไม่ค่อยมีการเปลี่ยนแปลงเช่น singletons หรือตัวชี้ฟังก์ชั่นการทำงานในห้องสมุดโหลดแบบไดนามิก การใช้ globals ที่เปลี่ยนแปลงได้ในแอพพลิเคชั่นแบบมัลติเธรดมีแนวโน้มที่จะนำไปสู่การติดตามบั๊กยากดังนั้นฉันจึงพยายามหลีกเลี่ยงสิ่งนี้ตามกฎทั่วไป
การใช้ทั่วโลกแทนที่จะผ่านการโต้แย้งมักจะเร็วกว่า แต่ถ้าคุณเขียนแอพพลิเคชั่นแบบมัลติเธรดซึ่งคุณมักทำอยู่ทุกวันนี้มันมักจะใช้งานไม่ได้ดี (คุณสามารถใช้เธรด - สแตติก .
ในเว็บแอปพลิเคชันภายใน enterprize สามารถใช้สำหรับเก็บข้อมูลเฉพาะเซสชัน / หน้าต่าง / เธรด / ผู้ใช้บนเซิร์ฟเวอร์ด้วยเหตุผลของการปรับให้เหมาะสมและเพื่อป้องกันการสูญหายของงานที่การเชื่อมต่อไม่เสถียร ตามที่ระบุไว้สภาพการแข่งขันจะต้องได้รับการจัดการ เราใช้อินสแตนซ์เดียวของคลาสสำหรับข้อมูลนี้และจัดการอย่างระมัดระวัง
ในตอนท้ายของวันโปรแกรมหรือแอปของคุณยังคงทำงานได้ แต่เป็นเรื่องของความเรียบร้อยและมีความเข้าใจอย่างสมบูรณ์ว่าเกิดอะไรขึ้น หากคุณใช้ค่าตัวแปรร่วมกันระหว่างฟังก์ชั่นทั้งหมดอาจเป็นเรื่องยากที่จะติดตามว่าฟังก์ชันใดกำลังเปลี่ยนแปลงค่า (ถ้าฟังก์ชันทำเช่นนั้น) และทำให้การดีบักเป็นล้านครั้งยากขึ้น
การรักษาความปลอดภัยน้อยหมายความว่าทุกคนสามารถจัดการกับตัวแปรถ้าพวกเขาจะประกาศทั่วโลกสำหรับการที่จะอธิบายนำตัวอย่างนี้ถ้าคุณมีความสมดุลเป็นตัวแปรทั่วโลกในโปรแกรมธนาคารของคุณฟังก์ชั่นผู้ใช้สามารถจัดการนี้เช่นเดียวกับเจ้าหน้าที่ธนาคารยังสามารถจัดการ สิ่งนี้จึงมีปัญหาผู้ใช้ควรได้รับฟังก์ชั่นการอ่านอย่างเดียวและถอนออกเท่านั้น แต่พนักงานของธนาคารสามารถเพิ่มจำนวนเงินเมื่อผู้ใช้ให้เงินสดในโต๊ะเป็นการส่วนตัว
ในแอ็พพลิเคชันแบบมัลติเธรดให้ใช้ตัวแปรโลคัลแทนตัวแปรโกลบอลเพื่อหลีกเลี่ยงสภาวะการแย่งชิง
สภาวะการแย่งชิงเกิดขึ้นเมื่อหลายเธรดเข้าถึงทรัพยากรที่ใช้ร่วมกันโดยมีอย่างน้อยหนึ่งเธรดที่มีการเข้าถึงเพื่อเขียนข้อมูล จากนั้นผลลัพธ์ของโปรแกรมไม่สามารถคาดการณ์ได้และขึ้นอยู่กับลำดับการเข้าถึงข้อมูลโดยเธรดที่แตกต่างกัน
เพิ่มเติมเกี่ยวกับเรื่องนี้ที่นี่https://software.intel.com/en-us/articles/use-intel-parallel-inspector-to-find-race-conditions-in-openmp-based-multithreaded- รหัส