เมื่อไรที่จะใช้ตัวแปรโกลบอล


22

ตกลงดังนั้นนี่เป็นคำถามสนับสนุนปีศาจจริงๆ

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

กรณีที่น่าสนใจสำหรับคำถามนี้ฟิลด์คลาสสแตติกสาธารณะแตกต่างจากโกลบอลอย่างไร


5
รหัสเสร็จสมบูรณ์รุ่นที่ 2 .313.3
Jerry Coffin

1
แอพพลิเคชั่นแบบมัลติเธรดนั้นต้องการตัวแปรระดับโลก
aqua


4
@aqua แอปพลิเคชันแบบมัลติเธรดเป็นที่ที่ตัวแปรทั่วโลกสามารถสร้างความเสียหายได้มากที่สุด ทุกคนเกลียดตรรกะการล็อคที่ซับซ้อน
luiscubal

1
@JerryCoffin หากโพสต์ลิงก์เป็นคำตอบโดยไม่ต้องอ้างอิงข้อความที่เกี่ยวข้องนั้นเป็นแนวปฏิบัติที่ไม่ดีดังนั้นการอ้างถึงส่วนของหนังสือโดยไม่ต้องอ้างถึงข้อความที่เกี่ยวข้อง โดยเฉพาะอย่างยิ่งเนื่องจากหนังสือไม่สามารถเข้าถึงได้อย่างอิสระและง่ายดายเหมือนกับหน้าเว็บ
Braden ที่ดีที่สุด

คำตอบ:


18

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

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


2
ฉันจะเรียกค่าคงที่ฟิลด์ที่เปลี่ยนไม่ได้
aioobe

14

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


คุณจะใช้โลกบริสุทธิ์สำหรับเรื่องนี้หรือสาธารณะคงที่ / ซิงเกิล?
ocodo

1
@Slomojo: แน่นอนไม่ใช่ซิงเกิล ขึ้นอยู่กับสถานการณ์ทั้งสถิตบนคลาสการกำหนดค่าหรือ globals ธรรมดาที่มีCONFIG_หรือCFG_คำนำหน้า
อานนท์

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

8

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

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


8
ฉันอาจแนะนำให้หลีกเลี่ยง Singletons
ocodo

ฉันไม่ได้บอกว่าซิงเกิลนั้นยอดเยี่ยม แต่ฉันก็ยังคิดว่าพวกเขาสามารถเอาชนะตัวแปรระดับโลกได้มากมาย
Davor Ždralo

ค่าคงที่จะต้องสามารถเข้าถึงได้ในพื้นที่ / โมดูลที่เกี่ยวข้องเท่านั้น ค่าคงที่TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOPมีความเกี่ยวข้องเฉพาะในไฟล์ / คลาส / ส่วนที่ 'ลูปเฉพาะนี้' ปรากฏขึ้น
คธูลู

1
เขตข้อมูลของซิงเกิลตันคือตัวแปรทั่วโลกดังนั้นฉันจึงไม่เห็นความแตกต่าง
sleske

1
@Cululhu ให้ฉันพูดตัวเอง: "ในสถานการณ์เหล่านั้นเมื่อคุณต้องการสิ่งที่จะมีจุดเชื่อมต่อทั่วโลก"
Davor Ždralo

6

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

สำหรับอีกตัวอย่างหนึ่งของบางสิ่งที่ฉันรู้สึกเช่นนี้ดูที่การใช้มิกซ์อินในทับทิม


ตัวอย่างกรณีการใช้งานที่คุณจะแนะนำสำหรับการใช้งานของ globals เหล่านี้คืออะไร?
ocodo

1
@Slomojo: ตัวอย่างของ globals ที่ฉันไม่รังเกียจคือการใช้ @ARGV และ $ _ ใน Perl ตัวอย่างที่ฉันคิดคือการใช้ globals สำหรับพารามิเตอร์ราคาถูกส่งผ่านไปยังรูทีนย่อย
btilly

5

มันคือทั้งหมดที่เกี่ยวกับเนมสเปซ

ลองนึกภาพว่าทุกคนในโลกนี้มีนามสกุลเดียวกัน ช่างเป็นระเบียบ

(ในอินเดียชาวซิกข์มีนามสกุลเดียวกันทั้งหมด: ซิงห์ - ลองดู)


6
มันเคยเป็นเรื่องเกี่ยวกับ namespaces แต่ตอนนี้มันเกี่ยวกับความปลอดภัยของด้าย
dan04

6
@ dan04 มันเกี่ยวกับการไม่มีการออกแบบที่น่ากลัวด้วยการกระทำที่น่ากลัวในระยะไกล
Tom Hawtin - tackline

2
@ ทอม: บางทีเราสามารถเรียกได้ว่าแก้มลิ้น, "การเขียนโปรแกรมควอนตัม"
Christopher Mahan

4

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

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

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

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


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

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

3

gotchas ทั้งสองที่มีกลมและเดี่ยวมีความสามารถในการทดสอบและการนำไปใช้งาน

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

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

โดยรวมแล้วฉันคิดว่าเหตุผลเหล่านั้นหมายความว่ากลมและเดี่ยวถูกใช้อย่างยอดเยี่ยมเท่านั้น


2

การพัฒนาระบบฝังตัวที่สำคัญมักเกี่ยวข้องกับการใช้ตัวแปรทั่วโลก

ขนาดสแต็กมีขนาดเล็กทุกอย่างได้รับการจัดสรรแบบคงที่ ( malloc()เป็นสิ่งต้องห้าม) ตัวแปรทั่วโลกจะถูกซ่อนจากภายนอกไลบรารีที่เป็นของพวกเขา


0

ในฐานรหัส VB6 ที่น่ากลัวซึ่งใช้ในทางที่ไม่ดีเช่นไม่มีวันพรุ่งนี้ฉันมีความผิดในการแนะนำใหม่:

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

ฉันคิดว่ามันเป็นหนึ่งในกรณีการใช้งานที่ถูกต้องสำหรับวัตถุระดับโลก

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