전역 변수를 사용해도 괜찮은 경우


22

자, 이것은 약간 악마를 옹호하는 질문입니다.

전역 변수는 언제 가능하며, 그렇지 않은 경우 대안으로 무엇을 사용 하시겠습니까?

이 질문에 대한 흥미로운 부가 사례는 공개 정적 클래스 필드가 글로벌과 어떻게 다릅니 까?


5
코드 완성 , 제 2 판, §13.3.
Jerry Coffin

1
다중 스레드 응용 프로그램 에는 전역 변수가 거의 필요 합니다.
아쿠아


4
@aqua 멀티 스레드 응용 프로그램은 전역 변수가 가장 손상 될 수있는 곳입니다. 누구나 복잡한 잠금 로직을 싫어합니다.
luiscubal

1
@JerryCoffin 관련 구절을 인용하지 않고 답변으로 링크를 게시하는 것이 좋지 않은 경우 관련 구절을 인용하지 않고 책의 섹션을 인용하는 것입니다. 특히, 웹 페이지처럼 책을 자유롭게 얻을 수 없기 때문에 쉽게 얻을 수 있습니다.
Braden Best

답변:


18

내가 아는 한 공개 정적 필드는 기본적으로 전역이므로 네임 스페이스를 방해하지 않는 것을 제외하고는 어디에서나 호출 할 수 있습니다.

내 코드에서 개인적으로 '전역'변수를 사용하는 유일한 시간은 변경할 수없는 공개 정적 필드의 형식입니다. 이 경우 프로그램의 다른 부분에 의해 가치가 약화되는 것에 대해 걱정할 필요가 없으며 물론 각 클래스에서 동일한 영구 값을 가진 수십 개의 변수를 갖는 것보다 훨씬 좋습니다.


2
불변 필드를 상수 라고 부릅니다 .
aioobe

14

개인적으로, 나는 런타임 구성을 위해 전역을 사용합니다-응용 프로그램 시작시 구성 속성이로드되고 자주 변경되지 않는 경우 (한곳에서만 변경되는 경우) 사용해야 할 수도있는 모든 메소드에 전달하는 것이 끔찍하고 오류가 발생하기 쉽습니다. 어느 시점에서. 메소드 서명 및 호출 사이트를 어지럽히 지 않고 가리지 않으므로 사용이 필요한 어느 곳에서나 사용할 수있는 것을 사용하는 것이 좋습니다.


이 또는 공용 정적 / Singleton에 순수한 전역을 사용 하시겠습니까?
ocodo

1
@ 슬로 모조 : 확실히 싱글 톤이 아닙니다. 상황에 따라 구성 클래스의 정적 요소 CONFIG_또는 CFG_접두사 가있는 일반 전역입니다 .
아논.

+1 내가 제안한 한 가지 변화는 "... 다른 모든 클래스의 다른 모든 메소드에 전달하기 쉬운 오류"라고 말하는 것입니다. 그렇지 않으면 그것이 생각하는 싱글 톤으로 클래스를 지정할 수 있습니다.
마이클 Durrant

8

실시간 / 내장 시스템을 제외하고는 상수 값에 대해서만 전역을 사용해야합니다. 문제가 없으면 문제를 해결할 수 없다고 생각되면 무언가 잘못한 것일 수 있습니다.

또한 Singleton 패턴을 살펴보면 글로벌 액세스 포인트가 필요한 상황에서 글로벌에 더 나은 솔루션을 제공합니다.


8
아마 싱글 톤을 피하는 것이 좋습니다.
ocodo

나는 싱글 톤이 훌륭하다고 제안하지는 않지만 여전히 전역 변수를 많이 능가한다고 생각합니다.
Davor Ždralo

상수 값은 관련 영역 / 모듈에서만 액세스 할 수 있어야합니다. 상수 TIMES_TO_ITERATE_THROUGH_THIS_PARTICULAR_LOOP는 '이 특정 루프'가 나타나는 하나의 파일 / 클래스 / 섹션에서만 관련됩니다.
Cthulhu 2019

1
싱글 톤의 필드 전역 변수이므로 차이점이 어떻게 보이지는 않습니다.
sleske

1
@Cthulhu는 "글로벌 액세스 포인트가 필요한 상황에서"라고 스스로 인용하도록하겠습니다.
Davor Ždralo

6

전역 변수의 문제점은 코드의 어느 곳에서나 변수를 알고 있어야한다는 것입니다. 그러나 특정 글로벌에 대해 알아야한다고 결정한 후에는 더 이상 글로벌을 사용하는 데있어 손실이 거의 없습니다. 따라서 제 생각에는 전역 변수가 거의 없어야하지만 소수는 최대 마일리지를 가져야한다는 것입니다.

이런 식으로 생각되는 다른 예는 Ruby에서 믹스 인 사용을 살펴보십시오.


이러한 글로벌 사용에 대해 어떤 사용 사례를 제안 하시겠습니까?
ocodo

1
@Slomojo : 마음에 들지 않는 글로벌의 예는 Perl에서 @ARGV와 $ _를 사용하는 것입니다. 내가 염두에 두는 예는 서브 루틴으로 전달되는 저렴한 매개 변수에 전역을 사용하는 것입니다.
btilly

5

네임 스페이스에 관한 것입니다.

세계의 모든 사람이 같은 성을 가지고 있다고 잠시 상상해보십시오. 엉망이야

(인도에서 시크교 인들은 모두 같은 성을가집니다 : Singh-한번보세요)


6
이전 에는 네임 스페이스에 관한 것이었지만 이제는 스레드 안전성에 관한 것입니다.
dan04

6
@ dan04 먼 거리에서 으스스한 행동을하는 끔찍한 디자인이 아닙니다.
Tom Hawtin-tackline

2
@Tom : 어쩌면 우리는 이것을 Qu 인 뺨이라고 부를 수 있습니다. "Quantum Programming"
Christopher Mahan

4

짧은 버전 : 프로그램에 대해 추론하기가 더 쉬울 때. 일반적으로 사례는 널리 사용되는 일부 유형의 전역 상태 또는 정적 자원입니다.

Long version : Tom Hawtin은 "먼 거리에서 으스스한 행동으로"라고 말했습니다 ... 전역과 정확히 같은 문제입니다. 사용되는 위치와 방법을 알아야합니다. 버그. 지역은 프로그램에 대해 추론하기 위해 프로그래머가 이해해야 할 범위를 줄이는 전략에 지나지 않습니다.

어디에 사용되는지 아는 문제의 또 다른 측면은 중복 전역을 사용할 수 있다는 것입니다.이 경우 대부분의 프로그램이 var1을 가져 와서 설정하고 var2를 사용하여 두 곳에서 사용하면 실제로 이상하게 될 수 있습니다 같은 정보. 특히 여러 사람이 동일한 코드를 작성하는 경우. IDE는 글로벌 비용을 줄이는 사용법을 찾는 데 도움이 될 수 있지만 중복에 대해서는 아무 것도하지 않습니다.

더 많은 지구본을 가질수록 지구에서 일어나는 일을 추적하기가 더 어려워집니다. 그것들은 적고 멀리 있어야합니다.


궁극적으로 변경 가능한 전역을 갖는 것은 꽤 나쁜 생각입니다. 임베디드 프로그래밍과 같이 매우 빡빡한 하드웨어 공간에서 작업하는 경우는 예외입니다. 최소한 정규 프로그래밍의 글로벌 후보는 클래스 또는 모듈의 정적 멤버로 소포되어야하며, 변경 가능한 것은 멀티 스레드 환경에서 작업 할 때 특별한 경우로 간주해야합니다. 잠금 / 선물 / 약속 또는 다른 스레드 / 거래 안전 방법 사용. -아무도 언급하지 않았기 때문에 식사 철학자들의 문제가 있습니다.
ocodo

1
스레드가 변경 가능한 전역을 다루기가 더 어려워지는 것은 의심의 여지가 없지만 이벤트로 인해 동일한 기본 문제가 발생할 수 있습니다. 나는 헴을 정적 멤버로 넣겠다는 제안에 동의하고, 나아가서 이상적으로는 PRIVATE 정적 멤버 여야한다고 말합니다.
jmoreno

3

글로벌과 싱글 톤의 두 가지 문제점은 테스트 가능성과 배포 가능성입니다.

테스트를 위해 계획된 글로벌 및 싱글 톤 수명을 다루기에는 지나치게 복잡한 테스트 장치가 너무 많았습니다. 그러한 객체가 명확하고 간단한 시작 및 해제 규칙을 가지고 있는지 확인하십시오.

배포 가능성에 대해서는 두 가지 경우를 고려해야합니다. 첫째, 글로벌 객체는 어떻게 살 것인가? 정적 또는 동적 라이브러리에 있습니까? 해당 전역 객체가 플러그인에 재사용되면 추가 사본을 얻을 수 있습니까? 둘째, 전역 객체가 병렬 응용 프로그램으로 드롭되면 어떻게됩니까? 스레드 안전합니까?

전체적으로, 나는 그 이유가 글로벌과 싱글 톤이 예외적으로 만 사용됨을 의미한다고 생각합니다.


2

중요한 임베디드 시스템의 개발에는 일반적으로 전역 변수 사용이 포함됩니다.

스택 크기가 작고 모든 것이 정적으로 할당되고 ( malloc()금지됨) 전역 변수는 자신이 속한 라이브러리 외부에서 숨겨집니다.


0

내일이없는 것처럼 전 세계를 학대하는 끔찍한 VB6 코드 기반에서 새로운 코드를 도입하는 것은 유죄입니다.

Global CsExt As New TheAppBeingRewrittenInCSharpWhileVb6CodeIsStillBeingMaintained

글로벌 객체에 대한 몇 가지 유효한 사용 사례 중 하나라고 생각합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.