Generic이란

Generic은 '타입(Type)을 미리 정하지 않고(포괄적인 상태로 해두고), 그것을 사용할 시점에 타입을 정의'하는 것을 말한다.
*generic : 포괄적인, 총칭의
https://fiftiesstudy.tistory.com/221

제네릭은 앞의 글에 나온 박싱, 언박싱의 단점을 극복하기 위해 만들었다고 한다.

우선 제네릭을 사용하지 않는 사례부터 천천히 예시를 들어보자.

타입이 고정적인 클래스의 단점

public class NoGeneric
{
    public int example;
    
    public void PrintExample()
    {
        Debug.Log(classInt);
    }
}

클래스 NoGeneric이 있다.
Int형 변수인 example을 가지고 있고,
그 example을 출력해주는 PrintExample 메서드를 하나 가지고 있는 클래스이다.

다른 클래스인 Test에서 이 기능을 사용하려면, 이렇게 하면 된다.

public class NoGeneric
{
    public int example;
    
    public void PrintExample()
    {
        Debug.Log(example);
    }
}
public class Test : MonoBehaviour
{

     private void Awake()
    {
        NoGeneric noGeneric = new NoGeneric();
        noGeneric.example = 111;
        noGeneric.PrintExample();
    }
}
-------------------------------
Log: 
111

여기까지는 제너릭을 사용하지 않은 보통의 방법이다.

하지만 PrintExample는 int형만 출력이 가능한데, 나중에 갑자기 추가로 float형을 출력하도록 구현해야한다면?

그때마다 이렇게 따로 함수와 변수를 만들어줘야한다.

public class NoGeneric
{
    public int example;
    public float example2;
    
    public void PrintExample()
    {
        Debug.Log(example);
    }
    public void PrintExample2()
    {
        Debug.Log(example2);
    }
    
}
public class Test : MonoBehaviour
{

     private void Awake()
    {
        NoGeneric noGeneric = new NoGeneric();
        noGeneric.example = 111;
        noGeneric.PrintExample();
        
        NoGeneric noGeneric = new NoGeneric();
        noGeneric.example2 = 3.14f;
        noGeneric.PrintExample2();
    }
}
-------------------------------
Log: 
111
3.14

음 정말 번거롭다.
지금이야 변수하나, 출력하는 한줄만 있는 간단한 코드라서 이렇게 떼울 수 있지만, 코드가 길어질수록 그러기는 힘들다.

타입이 다르다는 이유로 같은 기능의 코드를 여러번 쓴다는건 정말 싫을것같다. 수정이라도 하게된다면....😥

하지만 제네릭을 쓴다면?

Generic 사용 예제

public class YesGeneric<T>
{
    public T example;
    public void PrintExample()
    {
        Debug.Log(example);
    }
}

public class Test : MonoBehaviour
{
    private void Awake()
    {
        YesGeneric<int> genericTestA = new YesGeneric<int>();
        genericTestA.example = 1;
        genericTestA.PrintExample();

        YesGeneric<float> genericTestB = new YesGeneric<float>();
        genericTestB.example = 1.5f;
        genericTestB.PrintExample();

        YesGeneric<string> genericTestC = new YesGeneric<string>();
        genericTestC.example = "test";
        genericTestC.PrintExample();

        YesGeneric<NoGeneric> genericTestD = new YesGeneric<NoGeneric>();
        genericTestD.example = new NoGeneric() { classInt = 10 };
        genericTestD.PrintExample();
    }
}
-------------------------------
Log: 
1
1.5
test
NoGeneric

YesGeneric클래스 뒤에 <T>를 써주고, 담고있는 변수들에는 타입 대신 T 를 써준다.
Test클래스에서 YesGeneric클래스를 사용할때, 선언할 때에 클래스이름 뒤에 <타입>을 넣어주면 된다.

선언부분에서 익숙한 느낌이 든다면, 익숙한게 맞다. List나 Dictionary같은 클래스를 사용할때에도 우리는 이렇게 해왔었다.
ex) List intEx = new List();

아무튼,YesGeneric 클래스 부분을 보면 공백 제외하면 3줄밖에 안된다.
단 3줄로 사용할때에 int로,float으로,string으로, 심지어 클래스인 NoGeneric로도 타입을 넣어서 사용할 수 있다.

정리

항상 퇴근하고 쓰느라고 시간이 늦는다.. 원래 더 길게 쓰고싶었는데ㅠ
이번 글에서는 제네릭을 클래스와 필드 , 메서드에 사용했다.
다음글에서는 생성자와 프로퍼티에도 써먹을 수 있다는걸 이어서 정리하고, 내일 생각나는거 추가로 또 해야겠다.

 

 


 

프로퍼티와 생성자에 제네릭 활용

어제는 클래스에 Generic을 사용해서 예시를 보였었다.
오늘은 Property와 생성자 차례다.

public class YesGeneric<T>
{
    private T example;
    public T Example
    {
        get
        {
            return example;
        }
        set
        {
            example = value;
        }
    }

    public YesGeneric(T value)
    {
        Example = value;
    }

    public void PrintExample()
    {
        Debug.Log(Example);
    }
}

어제 작성했던 코드 YesGeneric를 그대로 활용했다.

기존에 Public 변수였던 example을 private으로 바꿔주었다. 그리고 프로퍼티 Example 을 추가해주었다.

생성자를 이용해 처음 클래스를 선언할때 부터 값을 지정해주면, 다른 클래스에서 사용하고자 할때는 이렇게 사용할 수 있다.

public class Test : MonoBehaviour
{
    private void Awake()
    {
        YesGeneric<string> genericTestA = new YesGeneric<string>("막상 해보니 별거 없다.");
        genericTestA.PrintExample();
    }
}
-------------------------------
Log: 
막상 해보니 별거 없다.

핵심은 어제 내용이고, 그냥 이정도도 같이 활용할 수 있다~ 정도로 알면 될 듯 하다.

커플링(Coupling)이란

커플링 : 두 오브젝트가 잘 알고 지내고 하드하게 연결되어 있는 정도를 뜻한다.

좋은 코드는 커플링이 적은 코드이다.

A 와 B 사이에 커플링이 심하다는 말은 A 와 B 가 서로 엮여있는 정도가 높다는 말이다.
때문에 A 가 없어지면 B 의 코드를 수정하기가 쉽지 않다.

커플링을 줄이면 A 와 B 가 서로 모르는 사이가 되기 때문에 둘 중 하나가 없어져도 코드를 수정하기 수월해지거나 수정할 필요가 없게 된다.

너무 좋은 글이 있어서 잠시 복붙좀 하겠다..


너무 좋은 설명이다.
A클래스에 있는 이벤트에 B와 C에서 수정을 해줄 수 있지만, 실행은 오직 A클래스에서만 할 수 있다.
그렇게되면 B와C가 A와 연결된것은 오직 이벤트 연결뿐이다.

커플링이라는 말 자체에 큰 의미는 없는것같다. 위 예제만으로 이해가 돼버린다.
https://ansohxxn.github.io/
구글링할때 되게 자주보이는 분이다. 디자인도 예쁘고 볼때마다 참 글을 잘 정리해서 쓰신다.

.

.

.
오늘 회사에서 CTO님이 내 일을 도와주셨는데, 내가 정확히 어떤 문제에 부딪혔는지도 제대로 설명을 못했었다.

이게 애매하게 알고있어서 설명을 제대로 못하는건지,
그냥 내가 말을 조리있게 못하는건지, 둘 다 인건지 모르겠다.

책을 좀 읽어야겠다.

 


작성일: 2022년 12월 14일

+ Recent posts