'객체지향'에 해당되는 글 1건

  1. 2008.09.01 [펌][수퍼개발자의 길 ⑦] 필수 아이템 5종 세트

[펌][수퍼개발자의 길 ⑦] 필수 아이템 5종 세트

Legacy 2008. 9. 1. 10:31
한번 읽어 보면 좋은 글인것 같아 스크랩 했답니다.
객체지향.. 여러분들은 정말 잘 알고 개발 하시나요?
전 좀 더 공부가 필요 한것 같내요.. ^^;

원본글 : http://www.zdnet.co.kr/builder/dev/etc/0,39031619,39172024,00.htm


[수퍼개발자의 길 ⑦] 필수 아이템 5종 세트

송기수(OpenSG.NET)   2008/08/31
[지디넷코리아]닷 넷 기술을 소개하는 세미나에 가면 늘 만나게 되는 얼굴이 있다. 바로 송기수 MVP다. 그는 언제나 발표할 내용에 비해 많은 양의 자료를 준비하는 욕심(?) 많은 기술 전도사다. 그런 탓일까? 이번 특집 원고 또한 원고 분량이 굉장히 많다. 아무리 자르고 눌러봐도 더 줄일 수가 없어서 기자가 쓸 페이지까지 밀고 올라왔다. 자 그럼 이제 기자의 소개보다 몇 배는 가치 있을 ‘송기수 식 고수되기 비법’에 대해 들어보자.
****************************************************************************

개발자의 길은 결코 쉽지 않다. 초보 개발자가 중급 고급이 되기 위해서는 중간 중간 넘어야 할 산이 있는데 이 산만 잘 넘으면 그 다음 고비까지는 수월하게 스스로의 힘으로 갈 수 있다. 지금부터 얘기 할 다섯 가지의 기술적인 내용은 특별한 우선순위는 없으며 이외에도 중요한 많은 내용이 있지만 지면상 다섯 가지만 얘기해 보려고 한다.

지금부터 전해드릴 내용은 수퍼 개발자가 되기 위한 충분조건이 아니라 필요조건임을 강조하고 싶다.

객체지향의 기본 : Reference type, Value type, Override, Overload
객체 지향적 언어는 여러 가지 특징을 가지고 있다. 상속과 다형성, 복잡한 구조를 숨기는 은닉성 등등. 하지만 500페이지가 넘는 객체지향 책을 꼼꼼히 다 읽기란 어려운 일이다. 또 ADO.NET 책을 사도 ASP.NET 책을 구입해도 앞에 1/2 정도는 객체지향에 대한 내용으로 채워져 있게 마련이다. 그만큼 중요한 탓이다. 그럼 객체지향의 의미를 제대로 이해하면서 작업하는 개발자는 얼마나 될까?

객체지향의 내용을 모두 이해하는 것은 힘들지만 가능한 일이다. 하지만 교과서적으로 OOP를 이해했다고 해서 이를 실무 프로젝트에 바로 적용하거나 기존의 라이브러리를 다 이해할 수 있는 것은 아니다. 반대로 OOP를 완전히 이해하지 않으면 실제 프로젝트에서 낭패를 보기 십상이다. 특히 자바의 개발자에 비해 닷넷 개발자는 OOP 객체의 개념에 약한 것이 사실이다.

자바 개발자들은 주로 C/C++이나 델파이 등과 같이 OOP에 익숙한 언어를 사용하거나 학습해본 사람들이 대부분이다. 대부분 메모리의 사용과 클래스, 객체 등의 개념에 익숙하다(물론 자바 개발자들 중 그렇지 않은 분들도 여럿 보긴 했다). 반면에 닷넷 개발자는 ASP와 VB와 같은 스크립트 언어나 객체지향이지 못한 언어의 백그라운드를 가진 분들이 대부분이다.

심지어 WebForm을 디자인하고 구현하면서 자신이 클래스를 정의하고 있는지를 모르는 분들도 있다. 또 어떤 닷넷 개발자는 한 번도 자신이 클래스를 정의해 본적이 없다고 얘기할 정도다. 그냥 이미 정의되어 있는 것만 쓰는 것이다.

닷넷 초창기에 이런 질문을 받은 적이 있다(윈도우 프로젝트의 경우에) 폼이 두 개 떴는데 A폼의 내용을 B로 어떻게 전달하죠? 이런 질문의 대부분은 VB 6.0 개발 백그라운드를 가지신 분들이 많이 한다. 클래스의 인스턴스 개념이 부족한 VB에서는 쉽게 폼 간의 참조가 가능하지만 완벽한 OOP 개념을 근간으로 한 닷넷 프레임워크에선 OOP와 객체의 형(type)을 이해하지 않고는 이해하기 어려울 수 있다.

초급 개발자가 실제 프로젝트를 진행하게 되면 책에 언급되지 않은 여러 가지 문제에 직면하게 된다. 그 많은 문제점 중에 OOP 개념을 정확히 이해하지 못해서 생기는 경우가 많다. 예를 들면 참조형식과 값 형식의 이해부족에서 오는 오류가 그 중 하나이다. 다 알겠지만 그래도 강조하는 의미서 한 번 더 확인하자면 참조형식과 값 형식의 가장 큰 차이점은 메모리의 사용일 것이다.

참조형식은 힙이라는 메모리 공간을 사용하고 값 형식은 스택이라는 메모리 공간에 저장되게 된다. 또한 특히 닷넷 프레임워크는 힙 메모리를 직접 접근 하는 것을 금지하고 있고 이 메모리 공간에 접근하기 위해서는 사용자가 선언한 변수를 통해서 접근이 가능하다. 물론 이 변수는 해당 힙 영역을 참조하고 있어야 한다.

그리고 이러한 변수들은 스택이라는 메모리 공간에 저장되게 된다. 또 다른 차이점으로는 값 형식은 값을 복사하고 참조형식은 참조를 복사한다는 것이다.

언어마다 조금씩 다르지만 힙에서 사용되는 타입과 스택에 사용되는 타입을 명시적으로 구분해 놓는 것이 일반적이다.

특히 타입에 대해서 엄격한 닷넷 프로그램 언어의 경우는 더욱 그러하다. 모든 클래스의 인스턴스는 힙에서 생성된다고 보면 된다. 그리고 숫자형과 날짜형, 열거형, 사용자 구조체 등은 스택에 생성된다. 이제 아래코드를 보자.

MyClass A = new MyClass();
..
MyClass B = A;
..

이 코드에 의한 메모리의 사용은 <그림 1>처럼 설명할 수 있다.

<그림 1> 객체의 참조


즉 하나의 클래스 인스턴스를 두 개의 객체변수 A, B가 참조하고 있는 것을 알 수 있다. 이 경우 A와 B는 같은 실체를 보고 있기 때문에 A와 B 어느 것을 통해서 내용을 수정해도 A, B에 변경된 내용이 모두 반영되어 보일 것이다. 이러한 것이 가능한 이유는 클래스 인스턴스가 참조형식 이기 때문이다.

이번에는 다음의 예를 보고 잘못된 곳을 30초 내에 찾아낼 수 있으면 나름대로 객체의 타입에 대한 이해를 하고 있다고 하겠다.


 <리스트 1> DatabaseUtil 클래스 정의


DatabaseUtil dbutil = new DatabaseUtil();
DataSet dsResult = new DataSet();
dsResult = dbutil.GetProductList("K001");
foreach (DataRow row in dsResult.Tables[0].Rows)
{

}
public class DatabaseUtil
{
public DataSet GetProductList(string Category) {…}


}



찾았는가? <리스트 1>의 내용을 보면 DatabaseUtil의 GetProductList 메소드를 이용하여 데이터셋 결과를 얻어오는 작업을 수행하고 있다. 이 메소드를 수행하기 전에 결과를 담을 DataSet 타입의 변수 dsResult와 DatabaseUtil 타입의 변수 dbutil을 각각 선언하고 또 각각 초기화 하였다.

여기서 어디가 잘못되었을까? 몇 줄 되지 않으니 자세히 행 단위로 코드를 살펴서 메모리맵을 그려보자.

첫 번째 행에서는 DatabaseUtil의 인스턴스가 힙에 선언되고 이를 참조할 DatabaseUtil형의 객체변수인 dbutil을 (스택에)선언함과 동시에 DatabaseUtil의 인스턴스를 dbutil에 참조하게 설정해주고 있다. 여기까지는 아무 문제가 없는듯하다.

두 번째 행에서는 결과를 저장할 DataSet 변수인 dsResult를 선언하고 초기화 하였다. 객체변수와 객체의 인스턴스가 역시 각각 스택과 힙 메모리에 저장되었다.

세 번째 행에서 GetProductList 메소드를 수행하고 이 메소드의 결과물(DataSet 인스턴스)을 dsResult에 저장했다. 그런데 여기가 문제다. dsResult는 이미 두 번째 행에 의해서 DataSet 인스턴스를 참조하고 있지 않은가? 그리고 3행 이후에서는 이 번 DataSet 인스턴스를 더 이상 접근할 수 없다. 왜냐면 더 이상 이 객체를 참조하고 있는 객체변수가 없기 때문이다.

즉 위의 코드대로라면 2면 행에서 생성된 DataSet 인스턴스는 생성된 후 한 번도 사용되지 못하고 버려지는 일종의 낭비되는 메모리이다. 물론 닷넷에서는 이와 같이 더 이상 참조될 수 없는 객체를 모아 모아서 한번 에 정리해주는 가비지콜렉터 라는 것이 있다.

방금 더 이상 접근되지 못하는 이 DataSet 인스턴스는 가비지콜렉터에 의해서 수집의 대상이 되기는 하나 필요하지 않다면 객체를 생성 안 하는 것이 더 효율적일 것이다.

따라서 <리스트 1>을 제대로 고쳐서 쓰면 다음과 같아진다.

DatabaseUtil dbutil = new DatabaseUtil();
DataSet dsResult = dbutil.GetProductList("K001");
foreach (DataRow row in dsResult.Tables[0].Rows)
{

}

즉 dsResult를 초기화 할 필요가 전혀 없다. 참조형과 값 형식에 대해서 확실히 알고 있는 개발자도 가끔 실수하는 부분이다. 또 실제 프로젝트에서 개발자 코드 리뷰를 하게 되면 항상 보게 되는 오류이기도 하다. 실제 프로그램 수행 시에 오류가 발생하거나 하는 것이 아니기 때문에 이미 완료된 프로젝트에서도 이와 같은 코드가 많이 있으리라 짐작된다.

이외에도 오버라이드와 오버로드 객체의 타입 캐스팅 등등 가장 기본적인 OOP의 개념에 대해서 모르고 있는 닷넷 개발자가 생각보다 많다. 지면 관계상 여기에 대한 내용까지는 할 수 없으나 꼭 한번 책이나 필자의 블로그를 통해 설명하려고 한다.

웹 애플리케이션의 기본 : 요청과 응답(Request and Response)
요청과 응답(Request and Response) 이 기본적인 웹의 실행방법을 모르는 웹 개발자는 없을 것이다. 하지만 요청과 응답 이것이 다 일까? 여기서도 필자가 역시 한 가지 질문을 하겠다. 본인이 닷넷 웹 개발 전문가라면 질문에 모두 답할 수 있어야 한다. 물론 질문이 명확하지 못해서 내용을 알고 있음에도 답을 못했다면 할 수 없으나 이 글을 읽고 답을 알았다면 팀에서 폭탄이 되지 않기 위해 열심히 노력해야 할 것이다.

1) 파일시스템에서는 파일의 확장자를 통하여 파일의 타입을 구분하고 해당 파일이 선택되면 연결된 애플리케이션을 구동하여 준다. 그럼 브라우저에서는 어떻게 서버에서 전달되는 콘텐츠의 형식을 구분할까?

예를 들면 같은 *.aspx 확장자를 가져도 어떤 경우에는 엑셀파일이 전달되어져 엑셀 프로그램이 구동되기도 하고 요청과 응답 그림파일이 전달되기도 하며 또 대부분의 경우는 html 형태로 브라우저가 표현해 주기도 하지 않은가?

분명 클라이언트는 서버에서 전달된 콘텐트의 타입을 구분하고 이에 맞는 애플리케이션을 로드해주고 있다. 무엇이 이러한 타입의 근거가 될까?

2) ASP.NET 웹 애플리케이션을 실행할 경우 실행 프로세스는 무엇인가?

1번의 답은 mime(마임) 이다. 이 마임 타입이 현재도 계속 확장되는 중이며, 당분간 브라우저가 html 형식이 아닌 바이너리 형식의 콘텐츠를 구분하는 유일한 구분자로 사용될 것이다.

2번의 경우는 질문이 조금 애매했다. 윈도우 서버 버전과 개발 환경에 따라서 약간씩 다를 수 있기 때문이다. 답은 aspnet_wp.exe 혹은 w3c.exe(윈도우 2003이후) 이다. ASP.NET 개발자라면 웹 애플리케이션의 실행 프로세스는 꼭 알아야 한다.

한번은 이런 질문을 받은 적이 있다. 웹 서버의 페이지 중에 한 페이지가 내부적으로 많은 작업을 수행해서 로딩시간이 길어지는데, 이 페이지를 A라는 사용자가 요청하고 있고 이 요청에 대해 아직 서버의 응답이 끝나지 않은 상태이다. 이 상황에서 B라는 사용자가 다른 페이지를 요청하면 사용자 B의 요청은 A의 요청에 대한 응답이 다 끝난 후에 처리 되나요? 어찌되나요? 왜 그런가요?

독자들의 생각은 어떤가? 필자는 이런 질문을 받을 때마다 종종 거꾸로 되돌려 질문한다. 이 경우는 아마도 ASP.NET의 실행프로세가 무엇이냐고 물어볼 것이다. 만일 정확하게 알고 있다면 좀 더 자세히 알려줄 수 있다. 프로세스를 알기 때문에 바로 쓰레드와 도메인 얘기를 할 수 있다.

하지만 실행 프로세스를 모른다면 이 경우 필자는 대부분 곤란에 처하게 된다. 질문자의 수준에 맞추어 질문에 성실히 답해줄 경우 설명이 한참 길어지게 될 뿐만 아니라 듣는 사람도 이해를 잘못하기 때문이다.

여러분이 웹 개발라면 html 태그나 비주얼스튜디오에서 드래그 앤 드롭에 의해서 제네레이션 된 코드를 사용하는 것뿐 아니라 웹의 본질과 이와 연관된 IIS와 같은 서버군의 특징이나 설정도 잘 이해해야 한다. 같은 맥락에서 서버뿐만 아니라 클라이언트의 실행 모델을 잘 이해하는 것이 중요하다.

순수 html의 경우는 별 문제가 없지만 스마트클라이언트와 같이 브라우저가 바이너리 파일을 실행하는 경우는 실행모델을 잘 이해하는 것이 프로젝트를 설계하거나 디버깅 하는데 많은 도움이 된다.

특히 프로젝트를 리드 하는 위치에 있는 개발자일수록 이러한 내용을 잘 이해하여 표준개발 가이드 및 템플릿을 만들어야 할 것이다. 자칫 잘못하면 엄한 표준가이드로 인해서 프로젝트가 산으로 갈수도 있다(이런 경우 정말 많이 봤다).

개발자의 기본 : 도움말(개발리소스)의 활용
도움말 문서를 최대한 활용하라. 너무 당연한 얘기일까? 하지만 필자의 경험에 의하면 많은 개발자들이 도움말을 잘 활용하지 못한다. 아니 활용하려 들지 않는다. 도움말 보다는 오히려 잘한다는 개발자의 블로그를 뒤척이거나 데브피아와 같은 개발 포털에 자신의 전체 코드를 올려놓고 누군가 고쳐주기를 원한다.

이는 사실 MSDN의 번역의 품질과도 어느 정도 상관이 있으며 MS가 약간의 원인제공을 한 부분이기도 하다.

웹 서버에 있는 데이터를 어떻게 로컬로 다운로드 할까? 데이터베이스에 있는 테이블과 웹 서비스를 통해서 전달된 데이터를 어떻게 통합해서 필터링할까? 혹은 어떻게 쉽게 하나의 그리드에 조인된 형태로 보여줄까?

대부분의 개발자는 이러한 각각의 요구사항 조각들이 설계자나 개발회의에 의해서 결정된 후에야 문서를 찾아서 보게 된다. 그런데 특정 문제를 해결하는데 있어서 국부적인 클래스의 몇 개 메소드만으로 해결되는 경우는 거의 없다.

또 해결됐다고 해도 더 좋은 방법이 다른 클래스를 통해서 있을 수도 있다. 그렇다고 시작 전에 방대한 MSDN 문서를 프로젝트 다 읽어 보라는 것은 아니다. 필자가 제안하고 싶은 것은 적어도 MSDN에 나와 있는 닷넷 프레임워크의 라이브러리에 있는 네임스페이스들만이라도 숙지하자는 것이다. 클래스도 아니다, 클래스의 커다란 모임인 네임스페이스의 이름과 내용을 숙지함으로서 앞으로 일어날 사용자의 요구사항에 능동적으로 대처하라는 것이다.

닷넷 프레임워크 1.1을 기준으로 네임스페이스는 약 50개였으나 버전이 올라감에 따라 그 수는 계속 늘고 있다. 또한 닷넷을 지원하는 서버프로그램(예, SQL, 익스체인지) 혹은 라이브러리군(WFP, WCF 등)이 추가될 때마다 역시 그에 해당하는 네임스페이스도 빠르게 늘어난다.

네임스페이스의 내용을 숙지하다 보면 그 동안 몰랐던 닷넷에 숨어있는 놀라운 기능들도 알게 될 것이다. 시간이 생각만큼 많이 걸리지 않는다. 오늘부터 하루에 10 개의 네임스페이스의 내용을 읽어보자. 네임스페이스 리스트는 MSDN에서 네임스페이스, 혹은 클래스라이브러리로 색인 검색하면 쉽게 찾을 수 있다.

닷넷의 기본 : CLR동작 방식
CLR은 자바로 말하면 버추얼머신이며 VB로 말하자면 런타임 라이브러리라고 할 수 있다. 닷넷 어셈블리로 만들어진 모든 실행파일들은 CLR을 통해서 실행된다. 많은 개발자들이 CLR에 무관심한 것은 아마도 현업 프로젝트를 수행함에 있어 직접적으로 CLR의 이해에 대한 요구를 많이 느끼지 못하기 때문일 것이다.

그럼에도 불구하고 CLR의 동작방식을 이해하는 것은 고급개발자가 되기 위한 기본적인 교양과목과도 같은 것이기에 매우 중요하다. 자, 여기서도 필자의 닷넷 골든 벨 질문 나간다. 아래와 같은 질문에 답을 할 수 있는지 스스로 테스트해보자.

1) 닷넷의 실행 어셈블리(exe,dll)를 구성하는 두 가지는 무엇인가?
2) C# 프로그램 소스가 있다. 이 소스코드가 실제 윈도우시스템에서 실행되기 위해서 몇 번 컴파일 되어야 하나?
3) 닷넷 두개의 닷넷 어셈블리가 있다. 이두개의 어셈블리는 무엇으로 구분되나? 즉 닷넷 어셈블리를 구분 짓는 항목은?

답은 1) IL 코드 + 메타 데이터
2) 2번: 한번은 개발자, 또 다른 한번은 실행 시에 JIT 컴파일러에 의해서 컴파일 됨
3) 이름, 버전, 컬처, 버전

개발자의 센스 : 툴의 활용
마지막으로 툴에 대해서 언급하고자 한다. 닷넷 개발이 가지는 장점은 통일된 툴에 있다고 할 수 있다. 닷넷 프로젝트를 진행할 때 개발 툴을 선정하느라 고민할 필요가 없다. 개발자의 입장에서 닷넷 프로젝트에 투입되면 으례 비주얼 스튜디오를 이용해서 개발하리라고 믿는다.

이는 곧 비주얼스튜디오 하나만 익숙하면 어느 닷넷 프로젝트에서건 툴에 대해서는 부담을 갖지 않아도 된다는 뜻이기도 하다. 비주얼스튜디오에는 데이터베이스 접속에서부터 IIS를 통한 웹 서버의 설정에 이르기까지 많은 기능들이 포함되어 있다.

필자는 오래 전에 비주얼스튜디오의 모든 메뉴와 툴바의 모든 버튼을 한 번씩 눌러가면서 기능을 확인한 적이 있다. 처음에는 별다른 의미를 두지 않고 시작했지만 메뉴와 버튼의 내용을 확인 하면서 많은 기능이 포함되었다는 걸 알고 무척 놀랐었다. 기본 비주얼스튜디오 상태에서는 많은 메뉴나 버튼은 비활성화 되어있다. 특정 메뉴나 버튼은 서버에 연결되거나 특정 아이템이 편집중일 때만 활성화되기 때문이다.

이런 메뉴나 버튼을 활성화시키기 위해서 늦게까지 많은 문서와 웹사이트를 뒤진 적지 않다. 이러한 와중에 학습 아닌 학습을 한 것이 나중에는 많은 도움이 되었다. 물론 이런 방법이 좋다는 것은 아니다. 어떠한 방법으로든 툴과 친해질 수만 있으면 된다.

또 비주얼스튜디오 이외의 툴들도 개발에 적지 않은 도움을 준다. 스마트클라이언트를 개발할 때 꼭 필요한 Fiddler나 웹 애플리케이션 개발 시에 쉽게 브라우저의 문서 DOM을 확인할 수 있게 해주는 IE Developer Toolbar 같이 개발환경에 따라 도움을 주는 여러 툴들이 있다. 이러한 툴들을 잘 이용하면 지레짐작으로만 넘겨 집었던 것들을 눈으로 쉽게 확인할 수 있게 되어 개발이 훨씬 능률적이다.

수퍼 개발자가 되려면 수퍼 점원처럼
지금까지 두서없이 수퍼 개발자가 되기 위한 아주 기본적인 내용을 적어봤다. 이와 관련되어 기술적인 내용은 아니지만 언급하고 싶은 것이 두 가지가 있다. 그 중 하나는 ‘지속적인 자기계발’이다. IT는 그 어느 산업하고도 달라서 기존기술의 감가상각이 상당히 심하다. 심할 때는 6개월 단위로 새로운 라이브러리나 기술들이 쏟아져 나온다. 닷넷 프레임워크 2.0이 2년 전에 나왔는데 벌써 내년에 3.5가 나온단다.

타 업계와 다르게 빠른 기술전환으로 인해 기존의 기술전문가들이 비교적 많은 기득권을 갖지 못하는 것은 어떻게 보면 장점일수도 있다. 즉 새로운 기술에 대해서 노력만하면 짧게는 1~2년에도 전문가의 위치에 설수가 있다.

거꾸로 얘기하면 기존 기술의 전문가라도 꾸준히 노력하지 않으면 금방 뒤처지는 것이 IT 산업의 특징이다. 물론 그렇다고 당장 먹고 사는데 문제가 되랴? 다만 선두에 서지 못한다는 것이다. 너무 겁먹지 않기를 바란다.

언급하고 싶은 또 다른 하나는 ‘서비스 정신’이다. 종종 개발자는 자신이 읽은 책이나 접한 세미나에서 얻은 지식을 맹신하는 경우가 있다. 자신의 지식과 상충되거나 PM이나 고객이 비합리적인 요구를 해오면 으례 개발자들은 자신을 방어하기 위해 화를 내거나 상대방과 싸워서 이기려고 한다. 하지만 어떠한 경우라도 화를 내거나 싸움을 하는 것은 결코 문제의 해결에 도움을 주지 못한다.

고객이나 PM 혹은 동료와 말다툼을 하고 난 후 대부분의 경우 개발자는 아주 빠른 시간 내에 후회를 한다는 것은 싸움보다 더 좋은 뭔가의 해결책이 있을 수 있다는 것을 반증하는 것은 아닐까? 꼭 싸워서 이기는 것이 진짜 이기는 것이 아닐지도 모른다.

대형 마트의 점원처럼 콜 센터의 안내원처럼 항상 웃는 얼굴로 개발도 서비스하는 정신으로 해보자. 물론 아주 어려운 아니 제일 어려운 일일 것이다. 하지만 이 컬럼의 주제가 수퍼(슈퍼마켓에서 일하는) 개발자가 되는 길 아닌가? ^_^; @


* 이 기사는 ZDNet Korea의 제휴매체인 마이크로소프트웨어에 게재된 내용입니다
: