본문 바로가기

Programming/C#

Static class VS Singleton Instance

반응형

서버사이드 OAuth2.0을 적용이후 클라이언트 사이드에서 Token을 관리해줄 관리자클래스를 하나 만들어야했다.


관리자를 이곳저곳 넘길일은 없을것 같아서(인스턴스일 필요 없을것 같아서) 그냥 static class로 만들려다가


선택에 근거가 될만한 다른 이유들이 있을까 하여 좀더 찾아보았다.


기본내용과 추가적으로 찾아본 내용이 있다.


기본적으로 싱글턴패턴은 인스턴스를 하나만 만들어 공유하듯 사용하는것이고 

static class는 인스턴스를 생성하지 않고 사용한다는 개념이다.


우선 아래는 C#에서 싱글턴패턴으로 작성된 TestClass이다.

가끔 인스턴스화 없이 사용할 수 있다는 수식때문에 혼동이 있을 수 있는데

외부에서 사용할때 new키워드(C#기준)로 인스턴스화를 별도로 해줄 필요가 없다는 말이지 인스턴스가 없다는 말은 아니다.

아래 코드를 보면 Property로 인스턴스를 가지고있다. Instance property가 호출시마다 해당 인스턴스를 리턴해준다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    public class TestClass
    {
        #region Instance Members
        private static readonly TestClass _Instance = new TestClass();
        public static TestClass Instance
        {
            get { return _Instance; }
        }
        #endregion
 
        void TestFunc()
        {
 
        }
    }
cs


사용시 Instance Property를 통해 인스턴스(유일한)를 가져와 멤버에 접근한다.

1
2
3
4
5
        [TestMethod]
        public void TestMethod1()
        {
            TestClass.Instance.TestFunc();
        }
cs


아래는 static class이다. 인스턴스화 할수없다(new 키워드 사용불가) 

1
2
3
4
5
6
7
    public static class SecondTestClass
    {
        public static void TestFunc()
        {
 
        }
    }
cs


인스턴스가 없기때문에 사용시 클래스명으로 바로 멤버에 접근 가능하다.

(이때 멤버는 static으로 선언되어야 한다.)

리뷰하면서 다시금 상기한것은 static class는 sealed(봉인) class 라는점이다. 상속할 수 없다.

1
2
3
4
5
        [TestMethod]
        public void TestMethod1()
        {
            SecondTestClass.TestFunc();
        }
cs


그 외에 힙/스택영역의 차이 인터페이스 상속가능여부 차이등도 있다.

또한 Static은 무조건 생성되어있지만 singleton은 사용하지 않으면 인스턴스를 생성하지 않는 차이점도 있다.

어떤방식이 보다 적합할지 선택하면 될 것 같다.


+보너스) 아래는 일반 클래스에 멤버로 static method가 있는 케이스이다.

1
2
3
4
5
6
7
    public class ThirdTestClass
    {
        public static void TestFunc()
        {
 
        }
    }
cs


Static class와 마찬가지로 class명으로 직접접근하여 멤버함수 호출이 가능하다.

정적클래스는 정적함수만들 가질 수 있지만 일반 클래스는 정적/일반 함수 모두를 가질 수 있기때문에 이런 구현이 가능하다.

1
2
3
4
5
        [TestMethod]
        public void TestMethod1()
        {
            ThirdTestClass.TestFunc();
        }
cs


단, 정적함수는 해당클래스의 인스턴스화 이후엔 접근이 불가능하다. (클래스명으로 직접접근만 가능하다.)

마찬가지로 클래스명 직접접근으론 일반반 멤버함수에 접근이 불가능하다.

두가지 타입의 함수를 모두 포함해야하는 경우 위와 같이 사용하면 될 것 같다.





반응형