[myLV.net 집필진 강좌 – 웅킹킹킹]
안녕하세요. 웅킹킹킹 입니다.
이번 시간에는 지난 번 제가 드렸던 문제에 대한 풀이를 하면서 LabVIEW에서 OOP 코딩을 한번 더 짚고 가도록 하겠습니다. OOP는 우리가 최종적으로 배우고자 하는 Actor Framework의 프로그래밍 패러다임이며 OOP의 기본 특성은 반드시 몸에 체화를 해야 할 정도로 익숙해져야 할 것 입니다. 이미 충분하게 이해와 숙련이 되신 분들은 이번 강좌는 Actor Framework를 가기 전 쉬어가는 시간으로 생각해도 좋습니다.
자, 그럼 이제부터 지난 강좌에서 드렸던 문제와 풀이입니다.
그림 1 Save 클래스 다이어그램
Save 클래스의 Method(Init, Write, Close)를 그림 1에서 볼 수 있으며 지난 강좌에서 우리는 LabVIEW에서 정적, 다이나믹 디스패치로 각각 구현해 보았습니다. 여기서 Init, Close는 정적 디스패치로, Write는 다이나믹 디스패치로 구현했습니다. 이렇게 다른 특성의 Method 타입으로 구현한 이유는 즉, 프로그램 리소스와 디버깅 입니다.
앞서 강좌 2에서 정적, 다이나믹 디스패치에 대한 설명을 했었습니다. 간단히 요약하자면 다이나믹 디스패치는 정적 디스패치에 비해 클래스 상속 관계에 따른 클래스 정보에 따라 Method가 선택되어 호출합니다. 그렇기 때문에 리소스를 정적 디스패치보다 많이 사용하게 됩니다.
그래서 반드시 다이나믹 디스패치 Method를 구현해야 하는 이유가 아니라면 정적 디스패치로 Method를 구현해야 합니다.
그림 2 Save 클래스의 Init.vi 블록다이어그램
그림 3 Save 클래스의 Close.vi 블록다이어그램
그림 2, 3은 정적 디스패치로 구현한 Save 클래스의 Method(Init, Close) 소스코드 입니다. Save 클래스의 하위클래스인 ASCII, Binary 클래스에서 두 Method의 코드가 달라져야 할 필요가 있을까요? 없습니다. ASCII, Binary 타입 둘 다 특정 데이터를 저장하기 위해선 모두 파일 열기, 파일 닫기 함수를 사용해야 하기 때문입니다.
ASCII, Binary 클래스는 상위 클래스인 Save 클래스로부터 상속받아 Method(Init, Close)를 그대로 재사용합니다.
물론 Save클래스의 Method(init, Close)를 정적이 아니라 다이나믹으로 구현하고 ASCII, Binary 클래스에서 Method(Init, Close)를 구현하지 않으면 자연스럽게 상위클래스인 Save 클래스의 Method를 사용하기 때문에 기능은 같습니다.
하지만 프로그램 리소스를 불필요하게 더 많이 사용하며 다이나믹으로 되어 있어 추후 프로그램 디버깅이나 소스코드 해석할 때 하위 클래스에서 다이나믹으로 구현된 같은 Method를 찾으려는 불필요한 수고가 생깁니다.
OOP의 핵심 중 하나는 제한사항을 둘 수 있다는 것입니다. 프로그래밍에 제한 사항을 두어서 프로그래머가 고려해야 할 부분을 줄이는 것에 그 목적이 있습니다.
정적으로 Method를 구현함으로써 하위클래스에서 다이나믹으로 호출될 수 있는 Method에 대한 고려하는 수고를 덜어냄으로써 프로그래머에게 효율적인 작업을 보장합니다.
그림 4 Save클래스의 Write.vi 블록다이어그램
그림 5 ASCII 클래스의 Write.vi 블록다이어그램
그림 6 Binary 클래스의 Write.vi 블록다이어그램
그림 4, 5, 6은 각 클래스의 다이나믹 Method(Write) 소스코드입니다. 예제 Save 프로그램의 상위 클래스인 Save 클래스의 Write는 프로그램상 실행이 되지 않는 Method 입니다. ASCII, Binary 두 가지의 타입으로 데이터를 저장하기 때문입니다.
Save 클래스의 Method(Write)를 빈 소스코드 상태로 구현하는 이유는 하위클래스인 ASCII, Binary 클래스에서 다이나믹 Method(Write)를 구현하여 호출하기 위해서는 상위 클래스에서도 같은 Method가 있어야 합니다.
클래스 상속관계에 따라 Method가 호출되는 다이나믹 디스패치 Method 특성에 맞추어 상위클래스와 하위클래스의 다이나믹 Method끼리 링크가 형성되어야 하기 때문입니다.
이렇게 구현된 다이나믹 Method는 입력되는 클래스(ASCII, Binary)에 맞추어 그림 5의 Write, 그림 6의 Write Method가 호출되어 실행이 됩니다.
그림 7 Main.vi의 소스 코드
그림 7을 보시면 ASCII, Binary 클래스에서 Method(Init, Close)가 없음에도 불구하고 호출되어 사용하고 있습니다. 어떻게 사용할 수 있었을까요?
바로 OOP의 핵심 코드 재사용입니다.
상위 클래스에서 구현된 Method의 경우, 상속 받은 하위 클래스에서 그대로 사용할 수 있습니다.
상위 클래스의 Method를 하위 클래스에서 바로 상속받아 사용함으로써 불필요한 중복 코드 작업을 방지하며 중복 코드가 방지됨으로써 자연스럽게 디버깅 작업 시 여기저기 흩어져있는 중복코드를 찾아 수정하는 수고를 덜어낼 수 있습니다.
그림 8 클래스 상속 예
그림 8은 앞선 강좌 2에서 상속에 대한 설명으로 사용한 그림입니다. 동물 클래스에서 먹는다, 잔다, 이동한다, 숨을 쉰다 등등의 Method를 구현하면 하위 클래스인 사람, 코끼리, 사자 클래스에서 바로 사용할 수 있습니다.
그리고 만약 ‘먹는다’ Method에 문제가 발생했을 때 사람, 코끼리, 사자 클래스에서 하나하나 찾아서 문제해결을 하는 것이 아니라 동물 클래스에서 ‘먹는다’ Method만 수정함으로써 모든 클래스에서의 문제가 해결이 됩니다.
하지만 이렇게 강력한 코드 재사용을 효과적으로 활용하기 위해서는 클래스의 상속관계의 설계를 잘해야 합니다. 프로그램을 구현하는 사람에 따라 전혀 다른 클래스 상속관계의 프로그램이 만들어 집니다. 혹자는 군더더기가 없는 효과적인 프로그램을 만들고 또 다른 이는 불필요한 요소가 많은 프로그램을 만들 수가 있습니다.
프로그래머는 세상을 컴퓨터 속에 구현하는 사람이라고 합니다.
그래서 OOP는 세상을 바라보는 눈, 프로그래머도 인문학적 부분이 필요하다는 말을 종종 OOP 관련 책에서 찾아볼 수 있습니다.
그림 1을 보시면 Save 클래스만이 ‘File Resource’라는 Data멤버를 가지고 있습니다. 그리고 우리는 지난 강좌에서 실습을 통해 구현을 했습니다.
LabVIEW에서 클래스를 만들고 Data멤버를 등록할 때 가장 강력한 제한사항을 걸어버립니다.
그림 9 Save 클래스의 Data멤버
그림 9는 프로젝트 상의 Save 클래스의 Data멤버 입니다. 빨간색 열쇠모양의 그림은 지난 강좌 2에서 설명했었던LabVIEW에서 설정하는 접근영역 중 Protected 설정 입니다.
이는 자기 자신 외에는 그 누구도 접근할 수 없다. 라는 강력한 제한 사항입니다. 상속해준 하위클래스에서도 접근을 할 수가 없습니다.
그림 10 클래스 Data 멤버 접근 제한
그림 10과 같이 하위클래스라도 접근할 때 저런 식으로 오류가 발생합니다.
그렇다면 어떻게 접근해야 할까요?
바로 Method를 만드는 것입니다. 자기 자신의 클래스 내에서 Method를 만들어서 Data멤버에 접근을 하고Method를 하위 클래스에서 사용하도록 하는 것입니다.
하위 클래스에서는 상속받은 상위클래스의 Method를 사용할 수 있기 때문입니다.
그림 11 클래스 새로 만들기 메뉴
그림 11의 ‘데이터 멤버 접근을 위한 VI…’는 반복적인 작업량을 줄이기 위해 자주 사용 할 수 밖에 없는 Data멤버를 접근하는 코드(Read, Write)를 구현하면서 Method를 생성합니다.
요약하자면,
① Data멤버는 Protected 접근 제한 영역 특성을 가진다.
② Protected 접근 제한은 자기 자신의 클래스 내에서만 접근이 가능한 영역이다.
③ 하위 클래스에서 상위 클래스의 Data멤버에 접근을 하기 위해선 Method를 만들어서 접근을 해야 한다.
④ ‘데이터 멤버 접근을 위한 VI…’는 Data멤버를 접근하는 코드(Read, Write)를 자동으로 구현하여 Method를 생성하는 기능이다.
앞서 1번 문제의 답변 참조.
다시 한번 요약 설명하자면,
① Write Method는 다이나믹 디스패치 Method이다.
② 다이나믹 디스패치는 클래스의 상속관계에 따라 Method에 입력되는 클래스 정보에 맞는 Method가 선택이 되어 호출된다.
③ 클래스 상속관계에 따라 Method가 호출되는 다이나믹 디스패치 Method 특성에 맞추어 상위클래스와 하위클래스의 다이나믹 Method끼리 링크가 형성되어야 한다.
④ 다이나믹 Method의 링크가 형성되기 위해선 상위 클래스에서 아무 기능을 하지 않는 Method일지라도 반드시 구현이 되어 있어야 한다.
지금까지 지난 강좌의 OOP 실습 내용을 한번 더 복습을 하는 시간을 가졌습니다. 이 강좌를 시작하면서 당부했듯이 Actor Framework의 프로그래밍 패러다임인 OOP의 기본을 탄탄하게 해야 합니다. 이 강좌 이외에도 ni.com에서 OOP를 검색하셔서 좀 더 많은 실습과 이론을 공부하시길 바랍니다.
다음 강좌에서는 드디어 Actor Framework에 대해서 시작할 예정입니다.
감사합니다.