[myLV.net 집필진 강좌 – 웅킹킹킹]
안녕하세요. 웅킹킹킹 입니다.
두 번째 강좌는 LabVIEW에서의 객체지향 프로그래밍(OOP)에 대해서 알아보겠습니다. 우선 OOP에 대해서 조금 아시는 분들은 객체, 클래스, 상속 등등의 명칭은 들어보셨을 텐데요.
이 중 헷갈리는 부분이 있습니다. “객체와 클래스는 뭐가 다른 건가??” 여러 문서나 책을 찾아보면 서로 다른 의미를 가지고 있지만 유사하며 각각의 의미를 애매하게 설명을 해줍니다.
일단 우리는 이 시점에서는 “객체와 클래스는 같다.” 라고 생각하고 넘어가도록 하겠습니다. 좀 더 강좌가 진행된 뒤 OOP, Actor Framework에 대해서 어느 정도 감이 잡힌 뒤에 같이 정확한 의미를 찾아보도록 하겠습니다.
우선 객체지향(클래스지향) 프로그래밍이기 때문에 가장 기본이 되는 ‘클래스’에 대해 알아보겠습니다.
그림 1은 NI DAQ 장비를 제어할 때 흔히 사용하시는 FGV 입니다. 여기서 DAQ 채널정보를 가지고 있는 Shift Register는 클래스의 Data 멤버가 됩니다.
케이스 문에서 Init의 DAQ 채널을 생성하는 코드는 클래스의 Method가 됩니다. 그림 1에서는 케이스문의 Init만 표현되어 있지만 실제로는 Init, Start, Read, Stop, Close 이렇게 다섯 개의 케이스 문이 존재합니다. 그래서 Method는 Init, Start, Read, Stop, Close 다섯 개가 됩니다. 좀 더 이해를 돕기 위해 FGV에 빗대어 설명했는데 이해가 좀 되시나요?
그림 2는 그림 1의 FGV를 클래스로 변환한 모습입니다. 파란 사각형의 열쇠모양이 있는 DAQ.ctl이 Data 멤버, 나머지 Init, Start, Read, Stop, Cloas.vi는 Method가 됩니다.
Data 멤버는 말 그대로 Data이기 때문에 Data 타입을 그림 3과 같이 지정해줘야 합니다. 명칭이 클래스 프라이빗 데이터의 클래스터라고 되어 있습니다. 그리고 그림 2를 보시면 작은 열쇠모양이 보입니다. LabVIEW 라이브러리에 존재하는 접근 영역과 같은 기능입니다. Data 멤버는 접근 영역 중 Private 접근 입니다. 해당 클래스 이외의 접근은 모두 차단당합니다.
그림 4처럼 외부 VI에서 클래스의 Data 멤버에 접근하려다 차단 당한 모습입니다. 클래스의 Data멤버는 오직 클래스의 Method에서만 접근을 할 수 있습니다.
이는 Data의 무분별한 사용을 막음으로써 프로그램 유지 및 보수에 엄청난 도움이 됩니다.
그림 4에서는 Data 멤버에 대한 접근이 차단되었지만 그림 5의 DAQ 클래스의 Init Method에서는 DAQ 채널을 생성하고 Data 멤버에 접근을 하여 DAQ 정보를 입력합니다.
나머지 Start, Read, Stop, Close Method에서도 필요한 코드와 함께 Data멤버에 접근하여 읽고 쓰기를 합니다.
정적 디스패치는 그림 6처럼 일반적으로 블록다이어그램에 SubVI를 끌어다 놓음으로써 호출하는 것과 같습니다. 즉, 컴파일 할 때 호출 SubVI가 고정이 되어 항상 같은 SubVI가 호출 되게 됩니다.
즉, 정적 디스패치 Method는 추후에 배우게 될 클래스 상속과 관계없이 Method가 변하지 않고 실행이 됩니다.
2) 다이나믹 디스패치
다이나믹 디스패치는 그림 7처럼 VI를 동적으로 호출하는 것과 같은 메커니즘입니다. VI 경로에 따라 호출 되는 VI가 결정이 되는 것처럼 클래스 상속관계에 따른 클래스 정보에 따라 Method가 선택되어 실행이 됩니다.
이 때 상속관계의 있는 다이나믹 디스패치 Method는 모두 같은 이름으로 만들어야합니다.
클래스 상속은 바로 이어서 설명드리겠습니다.
이러한 메커니즘 때문에 아무래도 다이나믹 디스패치가 정적 디스패치보단 리소스를 더 많이 사용하게 됩니다.
정적 디스패치, 다이나믹 디스패치는 이해가 어려울 수 있으나 바로 이어지는 클래스 상속관계와 간단한 실습을 통해 이해를 할 수 있을 것입니다.
그림 8은 상속관계에 대한 그림입니다. 동물은 사람, 코끼리, 사자의 상위계층이며, 사람, 코끼리, 사자는 상위 계층인 동물의 속성을 모두 가지고 있습니다.
Method로 표현하면 Eat.vi, Sleep.vi 등으로 표현할 수 있습니다. 이 Method는 하위계층이 모두 공통적으로 가지게 됩니다. 여기서 코끼리는 초식동물이고 사자는 육식동물입니다. 먹는 방식, 먹는 음식이 다르기 때문에 다이나믹 디스패치가 필요합니다. 앞서 다이나믹 디스패치에서 클래스 상속관계에 따른 클래스 정보에 따라 Method가 실행되는 메커니즘에 따라 Eat.vi Method가 실행될 때의 클래스 정보에 따라 코끼리의 Eat, 사자의 Eat가 실행이 됩니다.
그림 9는 LabVIEW에서의 클래스 상속을 설명합니다. ASCII와 Binary 서로 다른 형태로 Data를 저장할 때 상위 클래스로 Save 클래스, Save 클래스를 상속받는 하위클래스 ASCII, Binary로 클래스 상속 관계를 만들어 볼 수 있습니다.
이 때, 상위 클래스 Save클래스는 Data멤버로 File Resource, Method로는 Init, Write, Close를 다이나믹 디스패치로 만듭니다. 하위클래스 ASCII, Binary 클래스는 Write Method를 제외한 나머지는 모두 공통적으로 같기 때문에 Write Method만 다이나믹 디스패치로 만듭니다. 그래서 Write Method가 실행될 때의 클래스 정보가 ASCII일 때는 ASCII Write Method가 실행되고 Binary 클래스일 때는 Binary Write Method를 실행시킵니다.
다음 강좌에서는 그림 9의 예를 직접 LabVIEW로 만들어보면서 클래스, Data멤버, 정적 디스패치, 다이나믹 디스패치 Method와 상속에 대해서 더 많은 이해를 할 수 있는 시간을 가지도록 하겠습니다.