2010-06-30 7 views
27

일반적으로 글로벌 제품에 크게 의존하는 것을 피하는 것이 좋습니다. 정적 클래스와 메소드를 같은 것으로 사용하지 않겠습니까?전역 정적 클래스 및 메서드가 잘못 되었습니까?

+0

왜 "하루에 다시"라고 말합니까? 오늘 당황스럽지 않다고 생각할 이유가 있습니까? – jalf

+0

중복 : http://stackoverflow.com/questions/752758/is-using-a-lot-of-static-method-a-bad-thing 및 http://stackoverflow.com/questions/731763/should-c static-be-be-static이 될 수있는 방법과 http://stackoverflow.com/questions/2227793/why-are-static-classes-used ... 그리고 아마도 커뮤니티 위키 일 것입니다. – Abel

+0

전역 상태가 좋지 않지만 싱글 톤 (* 해결 방법 * 및 실제 해결책이 아님)이있는 이유는 초기화 순서 문제를 피할 수있는 게으른 구성 (액세스하는 동안 초기화 됨)에 의존하기 때문입니다. 그것들과 객체가 객체라는 사실은 객체를 상속 받고, 다형성을 사용하는 등 OOP 기술을 적용 할 수 있음을 의미합니다. – stinky472

답변

42

글로벌 데이터가 잘못되었습니다. 그러나 정적 메서드로 작업하면 많은 문제를 피할 수 있습니다.

나는 이런 식으로이 일에 Rich Hickey의 위치를 ​​가지고 그것을 설명하는거야 :

사용 정적 메서드와 클래스,하지만 글로벌되지 않은 데이터를 C#에서 가장 신뢰할 수있는 시스템을 구축하기 위해. 예를 들어 데이터 객체를 정적 메서드로 넘겨서 정적 메서드가 정적 데이터에 액세스하지 않으면 해당 입력 데이터에서 함수의 출력이 항상 동일하다는 것을 확신 할 수 있습니다. Erlang, Lisp, Clojure 및 기타 Functional Programming language이 취한 순위입니다.

정적 메서드를 사용하면 올바르게 프로그래밍 된 경우 한 번에 하나의 스레드 만 주어진 데이터 집합에 액세스 할 수 있기 때문에 다중 스레드 코딩을 크게 단순화 할 수 있습니다. 그리고 그것이 정말로 내려지는 것입니다. 글로벌 데이터를 갖는 것은 나쁜 일입니다. 왜냐하면 누가 어떤 스레드를 알고 있는지, 그리고 언제든지 알 수있는 사람이 변경할 수있는 상태이기 때문입니다. 그러나 정적 메서드는 작은 단위로 테스트 할 수있는 매우 깨끗한 코드를 허용합니다.

나는 이것이 C#의 OOP 생각 프로세스에서 떠오르면서 논쟁이 될 것이라는 것을 알고 있지만, 나는 더 정적 인 방법을 사용함에 따라 더 깨끗하고 안정적인 코드를 발견했다.

This video은 내가 할 수있는 것보다 더 잘 설명하지만 불변의 데이터와 정적 메서드가 매우 안전한 스레드 안전 코드를 생성하는 방법을 보여줍니다.


글로벌 데이터의 문제를 좀 더 명확히 설명합니다. 상수 (또는 읽기 전용) 전역 데이터는 변경 가능한 (읽기/쓰기) 전역 데이터만큼 큰 문제는 아닙니다. 따라서 글로벌 데이터 캐시를 갖는 것이 합리적이라면 글로벌 데이터를 사용하십시오! 어느 정도까지는 데이터베이스를 사용하는 모든 응용 프로그램이이를 가지고있을 것입니다. 왜냐하면 모든 SQL 데이터베이스는 데이터를 보유하는 거대한 전역 변수라고 말할 수 있기 때문입니다.

내가 위에서했던 것처럼 담요 명세서를 작성하는 것은 아마도 약간 강할 것입니다. 대신 글로벌 데이터를 사용하는 경우 로컬 데이터를 사용하는 것을 피할 수있는 많은 문제가 발생한다고 가정 해 보겠습니다.

Erlang과 같은 일부 언어는 해당 데이터에 대한 모든 요청을 처리하는 별도의 스레드에 캐시를 설치하여이 문제를 해결합니다. 이 방법을 사용하면 해당 데이터에 대한 모든 요청과 수정 사항이 원자 적이며 전역 캐시가 알 수없는 상태로 남지 않는다는 것을 알 수 있습니다.

+7

'글로벌 데이터가 잘못되었습니다. 그러나 정적 메서드로 작업하면 많은 문제를 피할 수 있습니다. " 이는 정적 데이터를 정적 메소드와 구별합니다. – decyclone

+1

전역 데이터를 사용하지 않고 각 요청에서 연결 당 10-20MB를 먹을 수있는 수십 개의 조회,지도 및 사전을 생성하는 IIS 서버에서 메모리를 낭비하지 않는 방법을 자세히 설명해 주시겠습니까? 블랭킷이 "글로벌 데이터가 나쁘다"는 말은 웹 개발자들로 하여금 잘못된 설계 선택을하도록 이끌 것입니다. – code4life

+0

아무도 정말로 국가 대 무국적자를 많이 사용하지 않는 것처럼 보입니다. imo가 여기 핵심입니다. 나는 blanket 문장에 대한 @ code4life가 오해의 소지가 있다는 것에 동의한다. (특히 첫 문장 일 때 특히 그렇다.) – Marc

0

아니요. 정적 (Static)은 실제로 인스턴스에 액세스 할 수있는 사람이 아닌 인스턴스화 된 시점, 위치 및 빈도를 결정합니다.

8

static은 반드시 글로벌을 의미하지 않습니다. 클래스와 멤버는 static private 일 수 있으므로 특정 클래스에만 적용됩니다. 즉, 적절한 방법으로 데이터 (메서드 호출, 콜백 등)를 전달하는 대신 많은 수의 public static 멤버를 갖는 것은 일반적으로 나쁜 설계입니다.

+4

'static private' 데이터는 문제의 클래스에게만 보이지만 전역 적입니다. –

+1

-1 어떤 개인용 정적 데이터인지 오해. 위의 주석을 참조하십시오. –

+8

개인 정적이 무엇을 의미하는지 잘 알고 있습니다. 비공개 정적 멤버는 전역 적으로 (즉, 선언 된 클래스와 다른 클래스에서) 액세스 할 수 없습니다. 당연히 그것의 자료는 세계적이고, 그러나 hackery없이 그것은 아주 접근 가능하지 않다 *. –

3

변경 가능 고정 변수은 단지 글로벌 상태이므로 불량합니다. 이 부분에 대해 알고있는 가장 좋은 토론은 is here, under the heading "Why Global Variables Should Be Avoided When Unnecessary"입니다.

정적 에는 종종 바람직하지 않게 만드는 몇 가지 단점이 있습니다. 가장 큰 단점은 다형성으로 사용할 수 없다는 것입니다.

+0

전적으로 "글로벌"의 정의에 따라 다릅니다. – GalacticCowboy

+0

최종 정적 변수에 대한 예외는 무엇입니까? –

+1

@Dean J - 사실, 나는 미치광이가 아닙니다. :) 그에 따라 내 대답을 업데이트하겠습니다. –

6

OO 개발에 정통하려는 경우 정체는 아마도 금형에 맞지 않습니다.

그러나 실세계는 이론보다 더 복잡하며 통계는 종종 개발 문제를 해결하는 데 매우 유용한 방법입니다. 적절하고 적절하게 사용할 때 사용하십시오.

1

전역 변수에 대한 나쁜 점은 전역 상태 변수를 갖는 생각입니다. 변수는 어디에서나 조작 할 수 있으며 멀리있는 프로그램 영역에서 의도하지 않은 부작용을 일으키는 경향이 있습니다.

정적 데이터은 글로벌 종류와 비슷하지만 전역 상태와 비슷합니다. 정적 방법 그들은 거의 나쁘지는 않지만, 그들은 무국적이라고 가정합니다.

2

다른 말로 추가하면, final static 변수가 잘됩니다. 상수는 좋은 것입니다. 유일한 예외는 /를 변경하기 쉽도록 특성 파일로 이동해야하는 경우입니다.

+2

이 질문은 C#으로 태그가 붙어 있으므로'final static' 대신'const'를 사용한다고 가정하겠습니다. – Powerlord

+2

질문은 언어에 구애받지 않는 태그가 붙어 있습니다. 아마도 빨래입니까? –

+0

두 주석의 Upvote; 저는 여전히 C#과 Java 사이를 빠르게 전환하지 않습니다. –

2

먼저, 이전 전역 변수가 그렇게 나쁜 이유는 무엇입니까? 언제 어디에서나 액세스 할 수있는 상태이기 때문에 언제든지 사용할 수 있습니다. 추적하기가 어렵습니다.

정적 방법과 같은 문제는 없습니다.

그 결과는 정적 필드 (변수)입니다. public 정적 필드를 클래스에 선언하면 그 변수가 전역 변수가되며 잘못된 것입니다.

그러나 정적 필드 을 개인으로 만들고 대부분의 문제가 해결되었습니다. 또는 더 좋게, 그들은 포함하는 클래스에 국한되며, 이는 그것을 해결할 수 있습니다.

2

정적 메서드는 스칼라에서 traits을 구현하는 데 사용됩니다. C#에서는 확장 메서드 (정적 인)가 part에서 해당 역할을 수행합니다. 이는 DCI 지지자들이 말한 것처럼 "higher order form of polymorphism"으로 볼 수 있습니다.

또한 정적 메서드를 사용하여 함수를 구현할 수 있습니다. F #이 modules을 구현하기 위해 사용하는 것입니다. (또한 VB.NET.) 함수는 (당연히) 함수 프로그래밍에 유용합니다. 때로는 그것들이 모델링되어야하는 방식 일뿐입니다 (Math 클래스의 "함수"와 같습니다). 다시 C# comes close 여기에 있습니다.

2
public class Foo 
{ 
    private static int counter = 0; 

    public static int getCounterValue() 
    { 
     return counter; 
    } 
    //... 
    public Foo() 
    { 
     //other tasks 
     counter++; 
    } 
} 

위 코드에서 얼마나 많은 Foo 객체가 생성되었는지를 알 수 있습니다. 이것은 많은 경우에 유용 할 수 있습니다.

정적 키워드는 전역이 아니며 클래스 수준에 있음을 알려주며 다양한 경우에 매우 유용 할 수 있습니다. 결론적으로, 클래스 수준의 것들은 정적이며, 객체 수준의 것들은 정적이 아닙니다.

관련 문제