NeoDEEX는 닷넷 환경의 어플리케이션 개발 프레임워크 입니다. 그렇다면 어플리케이션 개발 프레임워크란 무엇일까요? 이번 포스트는 바로 어플리케이션 개발 프레임워크로서 NeoDEEX를 이야기 하고자 합니다. 먼저 일반적인 개념의 어플리케이션 개발 프레임워크에 대한 개념을 설명하고 NeoDEEX가 어플리케이션 개발 프레임워크로써 어떠한 역할을 하는지 간략히 이야기하도록 하겠습니다.

어플리케이션 개발 프레임워크

어플리케이션 프레임워크라고도 불리는 어플리케이션 개발 프레임워크(이하 개발 프레임워크)는 어플리케이션을 개발하는 일련의 패턴을 말합니다. 좁은 의미의 개발 프레임워크는 어플리케이션 개발에 사용되는 클래스 라이브러리, 공통 모듈 등을 말하며 넓은 의미의 개발 프레임워크는 클래스 라이브러리 외에도 명명 표준, 코딩 표준 등 코드 작성에 관련된 일련의 규칙 뿐만 아니라 어플리케이션 아키텍처 표준까지 정의하고 있습니다.

닷넷 프레임워크도 개발 프레임워크 인가요?

닷넷 프레임워크를 개발 프레임워크라고 말하지 않습니다. 닷넷 프레임워크는 이름에 “프레임워크”라는 단어가 포함되어 있을 뿐 어플리케이션 개발 프레임워크라고 보긴 그 범위가 너무 광범위합니다. 닷넷 프레임워크는 일반적으로 어플리케이션 플랫폼(platform)으로 보는 것이 일반적이며 자바를 자바 플랫폼이라 부르지 개발 프레임워크라고 보지 않는 이유와 같습니다.

어플리케이션 개발 프레임워크들

개발 프레임워크들은 매우 다양합니다. Win32 어플리케이션을 작성할 때 많이 사용되는 MFC(Microsoft Foundataion Class) 라이브러리가 대표적인 “좁은 의미”의 개발 프레임워크 입니다. Win32 GUI 어플리케이션을 작성할 때 개발자들은 MFC를 통해 일련의 클래스들을 사용하여 일정한 패턴대로 개발을 하게 됩니다. 마이크로소프트의 Enterprise Library(EL) 역시 어플리케이션 개발 프레임워크입니다. EL은 좁은 의미의 개발 프레임워크라고 보기엔 좀 애매한데, EL이 Pattern & Practice의 가이드를 따라서 작성된 것이기 때문입니다. Pattern & Practice와 EL을 하나로 본다면 넓은 의미의 어플리케이션 개발 프레임워크라고 볼 수 있겠습니다. Spring.NET 역시 어플리케이션 개발 프레임워크입니다. 제가 아는 한 Spring.NET이 명명 표준이나 코딩 표준, 아키텍처 가이드 등을 제공하지 않기 때문에 좁은 의미의 개발 프레임워크라고 할 수 있겠습니다.

개발 프레임워크들은 대개 자바 환경에서 많이 개발되고 활용되곤 합니다. 그 이유는 자바 어플리케이션들이 상대적으로 닷넷에 비해 개발 생산성이 떨어지기 때문에 개발 프레임워크를 통해 개발 생산성을 올리기 위한 것으로 보입니다. 닷넷 환경에서는 통합된 개발 프레임워크가 사용되기보다는 데이터 액세스, 로깅(logging) 등등의 작은 클래스 라이브러리들이 지역적으로 사용되는 경우가 더 많은 것으로 보입니다.

어플리케이션 개발 프레임워크의 장단점

그렇다면 왜 개발 프레임워크를 사용하여 어플리케이션을 개발하는 것일까요? 개발 프레임워크를 사용하는 이유는 매우 다양합니다만 가장 큰 이유로는 개발 생산성 증대, 어플리케이션 품질 향상을 들 수 있습니다. 이외에도 개발 프레임워크를 적용함으로써 얻을 수 있는 장점은 여러 가지 입니다.

개발 생산성 증대

대부분의 개발 프레임워크는 코드를 작성하는데 편리한 클래스 라이브러리를 제공합니다. 개발자들은 이들 클래스 라이브러리를 통해 동일한 작업을 하는 코드를 보다 빠르고 간편하게 작성할 수 있습니다. 예를 들어 보죠. [리스트1]은 ADO.NET 만을 사용하여 데이터를 조회하여 업데이트하는 트랜잭션 코드 입니다.

   1: public void DoSqlDataAccess()
   2: {
   3:     string connString = ConfigurationManager.ConnectionStrings["TestDB"].ConnectionString;
   4:     string query1 = "SELECT * FROM Products WHERE SupplierId=@p0";
   5:     string query2 = "UPDATE ProductSummary SET Count=@p0 WHERE SupplierId=@p1";
   6:     SqlConnection conn = new SqlConnection(connString);
   7:     SqlCommand cmd1 = new SqlCommand(query1, conn);
   8:     SqlCommand cmd2 = new SqlCommand(query2, conn);
   9:     SqlDataAdapter adapter = new SqlDataAdapter(cmd1);
  10:     DataSet ds = new DataSet();
  11:     int count;
  12:  
  13:     cmd1.Parameters.AddWithValue("@p0", 1);
  14:     using (TransactionScope scope = new TransactionScope())
  15:     {
  16:         conn.Open();
  17:         try {
  18:             adapter.Fill(ds);
  19:             count = ds.Tables[0].Rows.Count;
  20:             cmd2.Parameters.AddWithValue("@p0", count);
  21:             cmd2.Parameters.AddWithValue("@p1", 1);
  22:             cmd2.ExecuteNonQuery();
  23:             scope.Complete();
  24:         }
  25:         catch (SqlException ex) {
  26:             WriteLog(ex.ToString());
  27:             Console.WriteLine(ex.ToString());
  28:         }
  29:         finally {
  30:             if (conn.State != ConnectionState.Closed) {
  31:                 conn.Close();
  32:             }
  33:         }
  34:     }
  35: }
  36:      
  37: // 일자별 로그 생성
  38: private static void WriteLog(string msg)
  39: {
  40:     string filename = String.Format("Result_{0}.log", DateTime.Today.ToString("yyMMdd"));
  41:     StreamWriter writer = new StreamWriter(filename, true, Encoding.Default);
  42:     writer.WriteLine(msg);
  43:     writer.Close();
  44: }

[리스트1] ADO.NET 만을 사용하는 데이터 액세스 코드

보다 실제적인 예를 위해 예외 처리 코드와 트랜잭션 처리를 포함했습니다만 코드의 양은 결코 적지 않습니다. 특히, 데이터를 조회하고 업데이트 하는 핵심 코드 외에도 트랜잭션 관리, 예외 처리, 데이터베이스 연결 관리 등 코드의 안정성 및 관리성에 관련된 부가적인 코드의 양이 많음에 주목할 필요가 있습니다.

다음 코드는 NeoDEEX에서 제공하는 데이터 액세스 기능(Fox Data Access)과 트랜잭션(Fox Transaction) 등의 기능을 사용한 코드로써 [리스트1]과 동등한 작업을 수행합니다.

   1: [Transaction]
   2: [AutoComplete]
   3: public void DoSqlDataAccess()
   4: {
   5:     string query1 = 
   6:         "SELECT * FROM Products WHERE SupplierId=@p0";
   7:     string query2 = 
   8:         "UPDATE ProductSummary SET Count=@p0 WHERE SupplierId=@p1";
   9:     DataSet ds;
  10:  
  11:     this.DbAccess.Open();
  12:     try {
  13:         FoxDBParamCollection parameters1 = 
  14:             this.DbAcess.CreateParametersWithValues("p", 1);
  15:         ds = this.DbAccess.ExecuteSQLDataSet(query1, parameters1);
  16:         int count = ds.Tables[0].Rows.Count;
  17:         FoxDBParamCollection parameters2 = 
  18:             this.DbAcess.CreateParametersWithValues("p", 1, count);
  19:         this.DbAccess.ExecuteSQLNonQuery(query2, parameters2);
  20:     }
  21:     finally {
  22:         db.Close();
  23:     }
  24: }

[리스트2] 개발 프레임워크(NeoDEEX)를 사용한 데이터 액세스 코드

[리스트1]의 코드와 [리스트2]의 코드를 비교해 보면 개발 프레임워크를 사용한 코드의 양이 훨씬 적다는 것을 알 수 있습니다. 단순히 코드의 양이 적다는 것보다 중요한 것은 개발자가 트랜잭션을 관리하는 코드나 예외 로그를 기록하기 위한 코드, 데이터베이스 연결을 관리하는 코드를 작성하지 않아도 된다는 점이 중요합니다. 개발자가 반복적으로 작성해야 하는 지루한 코드들을 개발 프레임워크에서 제공해 줌으로써 개발 생산성을 증대시킬 수 있습니다.

개발 프레임워크마다 개발 생산성 향상을 위해 제공하는 기능은 다양합니다. MFC는 다양한 클래스 라이브러리가 주종이며 Spring.NET도 비슷합니다만 코드 생성 도구를 통해 반복적이고 지루한 코드를 자동으로 생성하는 경우도 있습니다. NeoDEEX의 Fox Query가 바로 그러한 기능이지요. 지면 관계상 Fox Query에 대한 내용은 다른 포스트를 통해 소개하도록 하겠습니다.

어플리케이션 품질 향상

먼저 어플리케이션 품질이란 것이 무엇을 의미하는지 정의할 필요가 있겠습니다만 대개 높은 성능과 안정성, 정확한 계산 결과, 미려한 UI 등을 들 수 있습니다. 미려한 UI의 경우, 개발 프레임워크에 의해 향상된다기 보다는 디자인이 어떻게 적용되었는가에 영향을 받기 때문에 논외로 하겠습니다.

개발 프레임워크가 어떻게 어플리케이션 성능에 영향을 미치는가를 이해하기 위해서 대개 어플리케이션의 성능이 저하되는 이유를 파악해 볼 필요가 있습니다. 낮은 하드웨어 스펙, 잘못된 설계, 어플리케이션과 맞지 않는 어플리케이션 아키텍처, 낮은 개발자 수준 등등 다양한 이유로 어플리케이션 성능이 저하될 수 있습니다. 개발 프레임워크는 일정한 코드 패턴을 제시함으로써 개발자의 수준을 평준화 할 수 있습니다. 또 그 코딩 패턴은 일반적으로 권장되는 좋은 코딩 패턴이기 때문에 성능에 좋지 못한 영향을 주는 경우는 거의 없습니다. (물론 개발 프레임워크 자체가 성능적으로 문제를 유발하는 구조를 갖추고 있을 수도 있습니다)

예를 들어 [리스트1]의 코드는 성능을 충분히 고려한 코드 입니다. 매개변수를 사용하는 쿼리(Parameterize Query), 2개의 데이터 액세스에 대해 하나의 데이터베이스 연결 사용, System.Transactions 를 사용함으로써 트랜잭션 오버헤드 감소 등등이 성능을 고려한 코드라고 볼 수 있습니다. 개발자들의 수준이 모두 훌륭하여 이와 같은 성능적인 고려 사항을 모두 감안한다면 좋겠지만 실제 프로젝트에서는 이러한 성능관련 코드는 거의 고려대상이 아닙니다. 저희가 아는 한 모든 개발 프로젝트는 시간에 쫒기기 마련이고 이렇게 부족한 개발 기간 동안 권장되는 코딩 패턴을 적용하기 힘들기 마련입니다. 또 개발 프로젝트의 개발자들을 모두 고급 개발자로 채우기 또한 대단히 어렵습니다.

개발 프레임워크를 사용한 [리스트2]는 눈에 보이지 않지만 내부적으로 권장되는 코딩 패턴이 이미 적용되어 있으며 성능적인 고려가 적용된 코드가 사용되고 있습니다. 다시 말해 개발자의 수준에 상관없이 개발 프레임워크가 요구하는 코딩 패턴을 따르면 그 개발 프레임워크가 제공하는 수준의 성능을 낼 수 있다는 말이 됩니다. 이는 곧 개발 프레임워크가 개발자의 수준을 (상향 혹은 하향) 평준화시키게 되고 이로써 일정 수준의 성능이 나오게 된다는 말도 됩니다. [그림1]은 개발자 수준별 코드 품질과 평균적인 코드 품질을 보여주고 있습니다. 일반적으로 개발 프로젝트에서는 고급 개발자의 숫자가 절대적으로 부족하기 때문에 평균적인 코드 품질은 높지 않습니다. 하지만 개발 프레임워크가 제공하는 개발 패턴(클래스 라이브러리, 코딩 패턴)을 적용함으로써 초급 개발자도 일정 수준의 품질을 가진 코드를 작성할 수 있게 됩니다. 비록 개발 프레임워크가 고급 개발자의 코드를 하향 평준화 시킬 수 있지만 전체적으로 어플리케이션의 품질을 향상시키게 됩니다.

image

[그림1] 개발자 수준에 따른 코드 품질과 개발 프레임워크 적용 시 코드 품질

개발 생산성의 연장선 상에서도 어플리케이션의 품질을 향상할 수 있습니다. 다시 [리스트1]과 [리스트2]를 비교해 보면 단순히 코드가 짧다는 것 외에도 개발 프레임워크의 장점을 보여주고 있습니다. [리스트1]의 코드는 이 코드의 핵심이라 볼 수 있는 데이터 액세스(SQL 문장) 외에도 데이터베이스 연결, 트랜잭션 처리, 예외 처리, 로깅 등 다양한 코드가 많습니다. 반면 [리스트2]의 코드는 핵심적인 어플리케이션 로직(SQL 문장) 이외의 기능은 프레임워크에서 처리해 주는 것을 알 수 있을 것입니다. 개발자는 개발 프레임워크를 사용함으로써 어플리케이션 로직에 보다 집중할 수 있으며 보다 정확하고 빠른 SQL 문장을 작성할 여유를 가질 수 있으며 이는 곧 어플리케이션 품질 향상에 직결됩니다.

실례로, NeoDEEX를 적용한 P 사의 프로젝트에서는 초기 계획과 달리 개발 기간을 1개월 줄이고 테스트 기간을 1개월 늘렸습니다. 개발 기간이 1개월 단축되었음에도 불구하고 개발자들은 주어진 기간 내에 단위 테스트 수준을 완료한 프로그램을 모두 작성했고 그 결과 시스템 연계 테스트, 성능 테스트 등을 더 오래 할 수 있었고 아무런 문제 없이 시스템을 오픈할 수 있었습니다. 개발 프레임워크의 개발 생산성이 직접적으로 프로젝트 기간을 단축시키지 않더라도 어플리케이션의 품질을 향상시킬 수 있다는 것을 보여준 실질 프로젝트라고 할 수 있습니다.

편리한 유지보수

기업용 어플리케이션은 대개 수 년 동안 변화하는 비즈니스 환경을 반영하기 위해 지속적으로 업데이트되기 마련입니다. 다시 말해 개발이 완료된 기업용 어플리케이션이라 할지라도 지속적으로 기능이 추가/변경된다는 이야기 입니다. 유지보수 기간에 담당자의 변경이나 퇴사는 어플리케이션 유지보수의 어려운 점으로 작용하기 마련입니다.

개발 프레임워크를 적용함으로써 이러한 문제를 어느 정도 완화할 수 있습니다. 개발 프레임워크가 잘 적용된 어플리케이션은 서로 다른 개발자가 작성한 코드일지라도 그 패턴이 매우 유사하기 때문에 담당자의 변경이 발생하더라도 개발자가 빠르게 적응이 가능합니다.

또한 대부분의 개발 프레임워크들은 유지/보수의 편의를 고려하고 설계 개발되기 때문에 프로그램 코드의 변경을 최소화하면서 어플리케이션의 기능을 수정할 수 있습니다. NeoDEEX의 Fox Query 기능은 어플리케이션의 SQL 문장을 별도의 XML 파일에 기록해 두고 이 쿼리를 런타임에 수정할 수 있습니다. 만약 쿼리가 변경되면 SQL 문장이 기록된 XML 파일만을 수정하여 배포하면 됩니다(물론 컬럼 추가 등과 같은 UI 변경을 유발하지 않는 상황일 겁니다). Fox Query의 엔진(쿼리 매퍼라고 부릅니다)은 XML 파일의 변경을 탐지하고 이 파일을 다시 읽어 들이기 때문에 어플리케이션 중단 없이 변경된 쿼리를 적용할 수 있습니다.

개발 프레임워크의 단점

개발 프레임워크가 갖는 단점은 개발자들이 이 개발 프레임워크에 익숙해 지는데 시간이 필요하다는 것입니다. EL, Spring.NET, NeoDEEX 등의 상당한 수준의 개발 프레임워크들은 그 기능들이 매우 다양하기 때문에 개발자들이 이들 프레임워크에 익숙해지는데 일정 시간을 투자해야만 합니다. 다만, 개발 프레임워크의 기능/문서화 수준/교육 지원 여부에 따라서 이 시간은 각각 다릅니다. 일반적으로 기술 지원을 받을 수 있는 개발 프레임워크 제품은 개발자들이 개발 프레임워크에 익숙해지는데 적은 시간을 요구합니다.

개발 프레임워크가 내포할 수 있는 또 다른 단점은 개발 프레임워크 자체가 낮은 수준이거나 버그를 가지고 있는 경우 입니다. 예를 들어 개발 프레임워크가 성능을 장담할 수 없는 어플리케이션 아키텍처를 강요하거나 복잡한 구조로 인해 개발 생산성을 오히려 떨어트릴 수도 있습니다. 따라서 개발 프레임워크를 적용하고자 한다면 개발하고자 하는 어플리케이션에 가장 알맞은 개발 프레임워크를 선정하는 과정을 따라야 합니다. 이 과정을 무시했다가는 전체 어플리케이션 코드에 지대한 영향을 주는 개발 프레임워크 때문에 개발/운영/유지/보수에 어려움을 겪을 수도 있다는 것을 잘 인식해야만 합니다.

마지막으로 개발 프레임워크의 단점은 부족한 유연성입니다. 개발 프레임워크가 아무리 잘 설계되고 다양한 상황을 고려하여 코딩 패턴을 제시한다 할지라도 모든 상황을 다 커버할 수 있지는 않습니다. 따라서 개발 프레임워크가 지원하지 않는 시나리오의 코드를 작성해야 한다면 상당히 어려움이 따를 수 있습니다. 개발 프레임워크에 따라 유연성의 정도가 다를 수 있습니다. 어떤 프레임워크는 지원하지 않는 어플리케이션 아키텍처, 클라이언트/서버 통신 방법 등 시나리오를 전혀 지원하지 않을 거나 지원하기 위해 아주 많은 코드를 작성해야 할 수도 있으며 어떤 프레임워크는 다양한 커스터마이징 방법을 제공할 수도 있습니다. 대개의 경우 개발 프레임워크가 지원하지 않는 시나리오에서 개발 프레임워크를 적용하기는 쉽지 않습니다. 이 때문에 개발 프레임워크를 얼마나 손쉽게 커스터마이징 할 수 있는가가 개발 프레임워크를 우수성을 비교하는 잣대가 되기도 합니다.

NeoDEEX as Application Framework

NeoDEEX는 어플리케이션 개발 프레임워크 입니다. 특히, 데이터베이스 기반의 기업용 어플리케이션을 작성하는데 포커스가 가장 잘 맞추어��� 제품입니다. 소위 말하는 SI 프로젝트에서 NeoDEEX는 개발자들의 개발 생산성을 향상 시켜줄 것이며, 데이터베이스에 병목이 없다면 어플리케이션이 일정 수준 이상의 성능으로 작동할 수 있게 해주며, 어플리케이션의 품질이 일정 이상이 될 수 있도록 해줍니다. 또한 TheOne Technology의 프레임워크 교육, 컨설팅, 기술 지원을 통해 개발자들이 빠르게 NeoDEEX를 습득하고 개발할 수 있도록 지원하고 있습니다.

NeoDEEX를 통해 개발 프로젝트의 실패 가능성은 현저히 떨어진다고 자신 있게 이야기 할 수 있으며 실제 많은 NeoDEEX의 레퍼런스 사이트를 통해 우수성이 검증되었습니다.

NeoDEEX가 구체적으로 어떻게 개발자들의 개발 생산성을 향상시키며 어플리케이션 성능 향상을 위해 어떤 기능을 제공하는지 상세한 내용은 추후 NeoDEEX의 상세 기능을 다루는 포스트를 통해 소개하도록 하겠습니다.
경고 : 이 글을 무단으로 복제/스크랩하여 타 게시판, 블로그에 게시하는 것은 허용하지 않습니다.