SlideShare ist ein Scribd-Unternehmen logo
1 von 40
레거시 코드 활용 전략
4장 봉합 모델
5장 레거시 코드를 위한 도구


                                      아꿈사
               http://cafe.naver.com/architect1
                                      최유림
           http://blog.naver.com/sikyungelove
천공 카드 프로그래밍
• 데이터를 표현하기 위해 규칙에 따라 구멍을 뚫어
 사용하는 종이 카드로서 초기의 저장매체

• 천공 위치에 구멍을 뚫거나 뚫지 않음으로서 하나의
 비트를 나타날 수 있음




                    http://ko.wikipedia.org/wiki/%EC%B2%9C%EA%B3%B5_
                    %EC%B9%B4%EB%93%9C
봉합모델
레거시 코드를 위한 도구
정리가 안되지만 맞는 얘기들
봉합모델
레거시 코드를 위한 도구
정리가 안되지만 맞는 얘기들
봉합(Seams)

• 프로그램 안에서 동작을 변화시킬 수 있는 위치

• 동작을 변화시키기 위해 코드를 편집할 필요는 없
 음
bool CAsyncSslRec::Init()
{
         if(m_bSslInitialized){
                  return true;
         }
         m_smutex.Unlock();
         m_nSslRefCount++;

         m_bSslInitialized = true;

         FreeLibrary(m_hSslDll1);
         m_hSslDll1 = 0;
         FreeLibrary(m_hSslDll2);    •프로그램 안에서 동작을 변화시킬 수 있는 위치
         m_hSslDll2 = 0;
                                     •동작을 변화시키기 위해 코드를 편집할 필요는 없음
         if(!m_bFailureSent){
                  m_bFailureSent = true;
                  PostReceiveError(SOCKETCALLBACK, SSL_FAILURE);
         }

         CreateLibrary(m_hSslDll1, "syncesel1.dll");
         CreateLibrary(m_hSslDll2, "syncesel2.dll");

         m_hSslDll2->Init();
         m_hSslDll2->Init();

         return true;
}
bool CAsyncSslRec::Init()
{
         if(m_bSslInitialized){
                  return true;
         }
         m_smutex.Unlock();
         m_nSslRefCount++;

         m_bSslInitialized = true;

         FreeLibrary(m_hSslDll1);
         m_hSslDll1 = 0;                        동작을 변화시키지만
         FreeLibrary(m_hSslDll2);               코드는 편집하지 않도록 함
         m_hSslDll2 = 0;
                                                -> 코드와 테스트 분리 가능
         if(!m_bFailureSent){
                  m_bFailureSent = true;
                  PostReceiveError(SOCKETCALLBACK, SSL_FAILURE);
         }

         CreateLibrary(m_hSslDll1, "syncesel1.dll");
         CreateLibrary(m_hSslDll2, "syncesel2.dll");

         m_hSslDll2->Init();
         m_hSslDll2->Init();

         return true;
}
어떻게 하면
동작을 변화시키지만
코드는 편집하지 않도록 할까?
봉합(Seams)의 종류

• 프로그래밍 언어에 따라 서로 다름

• 프로그램 텍스트가 시스템 코드로 변형되는 시점
 에 따라 다름

• 컴파일 단계 : 전처리 봉합

• 링크 단계 : 연결 봉합

• 실행 단계 : 객체 봉합
전처리 봉합




• C, C++은 컴파일 하기 전에 매크로 전처리가 실
 행됨
• 전처리란 컴파일 전에 처리하는 매크로

• #로 시작 ex. #include <stdio.h>

• 전처리기를 통하여 동작을 변화시키지만 코드는
  편집하지 않도록 정의

• 많은 봉합의 기회 제공

• 전처리기 사용시 코드의 명료성이 떨어짐

• #define으로 정의되는 매크로는 단순히 텍스트 치환만
  수행

• 불명확한 버그를 숨기기 위한 매크로를 만들기 쉬움
bool CAsyncSslRec::Init()
{
         if(m_bSslInitialized){
                  return true;
         }
         m_smutex.Unlock();
         m_nSslRefCount++;

         m_bSslInitialized = true;

         FreeLibrary(m_hSslDll1);
                                                #include 문을 코드에 추가
         m_hSslDll1 = 0;                        -> PostReceiveError 매크로 정의
         FreeLibrary(m_hSslDll2);
         m_hSslDll2 = 0;                        -> 테스트용 전처리기 사용

         if(!m_bFailureSent){              -> 전처리 봉합
                  m_bFailureSent = true;
                  PostReceiveError(SOCKETCALLBACK, SSL_FAILURE);
         }

         CreateLibrary(m_hSslDll1, "syncesel1.dll");
         CreateLibrary(m_hSslDll2, "syncesel2.dll");

         m_hSslDll2->Init();
         m_hSslDll2->Init();

         return true;
}
연결 봉합

        • 링커는 컴파일러를 통해 만
         들어진 여러 Object File들을
         하나의 실행파일로 만듦

        • C, C++은 독립된 링커 존재

        • 자바는 링크 작업이
         보이지 않음
• 연결 봉합을 이용하는 가장 쉬운 방법은 바꾸고자
 하는 클래스나 함수를 위해서 별도의 라이브러리를
 만드는 것

• 테스트 해야 할 때 클래스나 함수 제작에 연결하지
 않고, 새로 생성된 클래스나 함수에 연결되도록 빌드
 스크립트를 변경하면 동작을 변화시키지만 코드는
 편집하지 않음

• 제 3의 라이브러리를 호출하는 코드 베이스를 가진
 경우 유용함
bool CAsyncSslRec::Init()
{
         if(m_bSslInitialized){
                  return true;
         }
         m_smutex.Unlock();
         m_nSslRefCount++;

         m_bSslInitialized = true;       PostReveiveError가 전역함수

         FreeLibrary(m_hSslDll1);        -> 라이브러리 생성
         m_hSslDll1 = 0;
                                         -> 동작 제거를 위해 라이브러리 연결
         FreeLibrary(m_hSslDll2);
         m_hSslDll2 = 0;                 -> 테스트 할때는 테스트 라이브러리와 연결
         if(!m_bFailureSent){            -> 실제 시스템 빌드시, 제작 라이브러리와 연결
                  m_bFailureSent = true;
                  PostReceiveError(SOCKETCALLBACK, SSL_FAILURE);
         }

         CreateLibrary(m_hSslDll1, "syncesel1.dll");
         CreateLibrary(m_hSslDll2, "syncesel2.dll");

         m_hSslDll2->Init();
         m_hSslDll2->Init();

         return true;
}
객체 봉합

• 객체지향 프로그램은 어떤 메소드가 실행될지
 정의하지 않음

• 같은 이름을 가지는 메소드가 하나 이상 있을 수
 있음

• 주변 코드 변화 없이 어떤 메소드가 호출될지 변
 경할 수 있는 경우가 객체 봉합
bool CAsyncSslRec::Init()
{
         if(m_bSslInitialized){
                  return true;
         }
         m_smutex.Unlock();
         m_nSslRefCount++;

         m_bSslInitialized = true;
                                             PostReveiveError를 오버라이드 하는
         FreeLibrary(m_hSslDll1);
         m_hSslDll1 = 0;                     테스트용 하위 클래스 객체 생성
         FreeLibrary(m_hSslDll2);            -> 동작을 변화시키지만
         m_hSslDll2 = 0;
                                                코드는 편집하지 않도록 함
         if(!m_bFailureSent){
                  m_bFailureSent = true;
                  PostReceiveError(SOCKETCALLBACK, SSL_FAILURE);
         }

         CreateLibrary(m_hSslDll1, "syncesel1.dll");
         CreateLibrary(m_hSslDll2, "syncesel2.dll");

         m_hSslDll2->Init();
         m_hSslDll2->Init();

         return true;
}
봉합모델
레거시 코드를 위한 도구
정리가 안되지만 맞는 얘기들
리팩토링

• 소프트웨어의 내부 구조에 가해지는 변화

• 소프트웨어에 존재하는 동작을 변경하지 않음

• 이해하기 쉽게 변경

• 직접 할 수도 있고, 도구를 이용 할 수도 있음
자동화된 리팩토링 도구

• 언어마다 리팩토링 도구들이 존재

• 통합개발 환경으로 구성되거나 분리됨
리팩토링 검증

• 리팩토링 과정에서 버그가 생길 수 있음

• 자동화된 리팩토링 도구에 버그가 있을 수 있음

• 리팩토링 후 동작을 변경시키지 않는지 검증해야
 함
리팩토링 예제
public class A{                           public class A{
 private int alpha = 0;                    private int alpha = 0;
 private int getValue(){                   private int getValue(){
  alpha++;                                  alpha++;
  return 12;                                return 12;
 }                                         }
 public void doSomething(){                public void doSomething(){
  int v = getValue();                       int total = 0;
  int total = 0;                            for(int n=0; n<10; n++){
  for(int n=0; n<10; n++){                   total += getValue();
   total += v;                v를 제거하라!!     }
  }                                        }
 }                                        }
}
리팩토링 예제
public class A{                            public class A{
 private int alpha = 0;                     private int alpha = 0;
 private int getValue(){                    private int getValue(){
  alpha++; // alpha 1 증가                     alpha++; // alpha 10 증가
  return 12;                                 return 12;
 }                                          }
 public void doSomething(){                 public void doSomething(){
  int v = getValue();                        int total = 0;
  int total = 0;                             for(int n=0; n<10; n++){
  for(int n=0; n<10; n++){                    total += getValue();
   total += v;                    리팩토링 후     }
  }                              동작이 변경됨    }
 }                                         }
}

         테스트 루틴을 두어 리팩토링 후 수행!!
                              ex) alpha 값 검증
어떻게 검증할까?
xUnit 단위 테스트 프레임워크

• 소프트웨어의 함수나 클래스 같은 서로 다른 구성
 원소(단위)를 테스트 하는 프레임워크

• 같은 테스트 코드를 여러번 작성하지 않음

• Java 단위 테스트는 jUnit
 C++ 단위 테스트는 CppUnit
 .NET 단위 테스트는 Nunit

• 오픈소스로 사용 가능
Junit
• xUnit의 자바버전

• TestCase라는 클래스로 하위 클래스화함으로써
 테스트 루틴을 작성
import junit.framework.*;

public class FormulaTest extends TestCase{
                      // testXXX() 형식의 메소드
          public void testEmpty(){ // 테스트 하려는 내용(빈 경우 테스트)
          // 확인코드 // 코드포함가능(새로운 객체 생성, value 메소드 이용)
                   assertEquals(0, new Formula("").value());
          }
          public void testDigit(){
                   // 값이 일치하면 테스트 통과, 아니면 테스트 실패
                   assertEquals(1, new Formula("1").value());
          }
}

            메소드 별로 서로 영향을 주지 않기 위해

     각 테스트 메소드 용으로 완전히 분리된 객체 생성
public class EmployeeTest extends TestCase{
          private Employee employee;
                         //테스트 메소드가 실행되기 전에 각 테스트 객체에서 실행됨
          protected void setUp(){
                   //각 테스트에서 사용할 객체 생성
                   employee = new Employee("Fred", 0, 10);
                   TDate cardDate = new TDate(10, 10, 2000);
                   employee.addTimeCard(new TimeCard(cardDate, 40));
          }

       public void testNormalPay(){
                //setUp에서 생성된 하나의 employee가
                  한번만 시간카드의 봉급 계산하는지 검사
               assertEquals(400, employee.getPay());
       }

       public void testOvertime(){
                TDate newCardDate = new TDate(11, 10, 2000);
                employee.addTimeCard(new TimeCard(newCardDate, 50));
                //setUp에서 생성된 하나의 employee가
              초과 근무 조건을 발생시키는지 검사
                assertTrue(employee.hasOvertimeFor(newCardDate));
       }
}
이거 합시다~
(이미 했지만~)
Fit
• 통합 테스트 프레임워크

• 입력값, 출력값을 표로 작성

• HTML 형식으로 저장

• 작성한 표가 테스트 루틴이 됨

• 테스트를 통과하면 표의 셀을 녹색으로 표시

• 테스트를 실패하면 표의 셀을 빨간색으로 표시
Fit
• 고객(기획자)이 표를 작성

• 고객과 개발자 간의
 의사소통이 쉬움

• 처음에는 모두 실패

• 개발 완료시, 테스트 모두 통과
Fitnesse
• 위키에 적용된 FIT

• 빠르고 쉽고 테이블을 디자인 가능

• 웹 형태로 제공되어 누구나 쉽게 테스트케이스의
 공유 및 작성, 테스트가 가능
!define TEST_SYSTEM {slim}

!define COLLAPSE_SETUP {true}
!define COLLAPSE_TEARDOWN {true}

!|Create Programs                   |
|Name |Channel|DayOfWeek|TimeOfDay|DurationInMinutes|id? |
|House|4    |Monday |19:00 |60        |$ID=|
NTAF
• 테스트 흐름이 획일적인 Fitnesse의 단점을 보완

• If, Loop, Parallel 등 키워드 추가

• 로그 확인, 변수 연산 등 가능
봉합모델
레거시 코드를 위한 도구
정리가 안되지만 맞는 얘기들
정리가 안되는 맞는 얘기들

• 재사용 가능하도록 작은 조각들로 쪼개 프로그램
 을 작성하는 것이 좋음

• 자주 독립적으로 재사용되는 모듈화는 어려운 일

• 테스트하면 코드를 다른 각도에서 볼 수 있게 됨

• 테스트 루틴을 작성하려 할 때서야 기존의 코드가
 얼마나 엉성하게 짜여져 있는지 알게 됨
비트 경제(?)와 공짜 테스트

     나는 개발자
     개발 해서 돈을 벌지~



  그런데 내가 왜 개발하면서
  테스트 코드를 만들어야지?
 테스트는 QA가 알아서 할텐데
         뭣하러 공짜로?
공짜가 아니야~
개발 단계에서 작성하는 테스트 코드는
QA가 진행하는 테스트보다
비용과 시간이 절감되지



기획과 합심하면 QA쯤이야
  그 화폐를 우리 손으로~
QA는 개발자가
할 수 없는 테스트를 찾아서..
레거시 코드 활용 전략
4장 봉합 모델
5장 레거시 코드를 위한 도구




               감사합니다

Weitere ähnliche Inhalte

Was ist angesagt?

[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로Oracle Korea
 
프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js functionYoung-Beom Rhee
 
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)Suwon Chae
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기jongho jeong
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리ETRIBE_STG
 
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitiveNAVER D2
 
자바 테스트 자동화
자바 테스트 자동화자바 테스트 자동화
자바 테스트 자동화Sungchul Park
 
프론트엔드스터디 E03 - Javascript intro.
프론트엔드스터디 E03 - Javascript intro.프론트엔드스터디 E03 - Javascript intro.
프론트엔드스터디 E03 - Javascript intro.Young-Beom Rhee
 
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)Sang Don Kim
 
Javascript 교육자료 pdf
Javascript 교육자료 pdfJavascript 교육자료 pdf
Javascript 교육자료 pdfHyosang Hong
 
비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기jeong seok yang
 
데이터베이스패턴
데이터베이스패턴데이터베이스패턴
데이터베이스패턴Suan Lee
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍Young-Beom Rhee
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기Yongha Yoo
 
java 8 람다식 소개와 의미 고찰
java 8 람다식 소개와 의미 고찰java 8 람다식 소개와 의미 고찰
java 8 람다식 소개와 의미 고찰Sungchul Park
 
자바8 람다식 소개
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개beom kyun choi
 
Angular2 가기전 Type script소개
 Angular2 가기전 Type script소개 Angular2 가기전 Type script소개
Angular2 가기전 Type script소개Dong Jun Kwon
 
자바스크립트 함수
자바스크립트 함수자바스크립트 함수
자바스크립트 함수유진 변
 
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It종빈 오
 

Was ist angesagt? (20)

[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
[Main Session] 미래의 Java 미리보기 - 앰버와 발할라 프로젝트를 중심으로
 
프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function프론트엔드스터디 E04 js function
프론트엔드스터디 E04 js function
 
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
테스트 가능한 소프트웨어 설계와 TDD작성 패턴 (Testable design and TDD)
 
Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기Javascript 조금 더 잘 알기
Javascript 조금 더 잘 알기
 
Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리Javascript 완벽 가이드 정리
Javascript 완벽 가이드 정리
 
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
[D2 COMMUNITY] ECMAScript 2015 S67 seminar - 1. primitive
 
자바 테스트 자동화
자바 테스트 자동화자바 테스트 자동화
자바 테스트 자동화
 
프론트엔드스터디 E03 - Javascript intro.
프론트엔드스터디 E03 - Javascript intro.프론트엔드스터디 E03 - Javascript intro.
프론트엔드스터디 E03 - Javascript intro.
 
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
[Td 2015]너에게만 나는 반응해 반응형 응용프로그램(이규원)
 
Javascript 교육자료 pdf
Javascript 교육자료 pdfJavascript 교육자료 pdf
Javascript 교육자료 pdf
 
비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기비전공자의 자바스크립트 도전기
비전공자의 자바스크립트 도전기
 
데이터베이스패턴
데이터베이스패턴데이터베이스패턴
데이터베이스패턴
 
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
 
스위프트 성능 이해하기
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
 
java 8 람다식 소개와 의미 고찰
java 8 람다식 소개와 의미 고찰java 8 람다식 소개와 의미 고찰
java 8 람다식 소개와 의미 고찰
 
자바8 람다식 소개
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개
 
JDK 변천사
JDK 변천사JDK 변천사
JDK 변천사
 
Angular2 가기전 Type script소개
 Angular2 가기전 Type script소개 Angular2 가기전 Type script소개
Angular2 가기전 Type script소개
 
자바스크립트 함수
자바스크립트 함수자바스크립트 함수
자바스크립트 함수
 
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
[WELC] 22. I Need to Change a Monster Method and I Can’t Write Tests for It
 

Ähnlich wie 120908 레거시코드활용전략 4장5장

About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10흥배 최
 
Domain Specific Languages With Groovy
Domain Specific Languages With GroovyDomain Specific Languages With Groovy
Domain Specific Languages With GroovyTommy C. Kang
 
Sonarqube 20160509
Sonarqube 20160509Sonarqube 20160509
Sonarqube 20160509영석 조
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화sung ki choi
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Testbeom kyun choi
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.Ryan Park
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Ryan Park
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기Wonchang Song
 
C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기Heo Seungwook
 
C# Game Server
C# Game ServerC# Game Server
C# Game Serverlactrious
 
Ai C#세미나
Ai C#세미나Ai C#세미나
Ai C#세미나Astin Choi
 
Refactoring - Chapter 8.2
Refactoring - Chapter 8.2Refactoring - Chapter 8.2
Refactoring - Chapter 8.2Ji Ung Lee
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 명신 김
 
Secrets of the JavaScript Ninja - Chapter 12. DOM modification
Secrets of the JavaScript Ninja - Chapter 12. DOM modificationSecrets of the JavaScript Ninja - Chapter 12. DOM modification
Secrets of the JavaScript Ninja - Chapter 12. DOM modificationHyuncheol Jeon
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택JinTaek Seo
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storageJinKyoungHeo
 
Design patterns
Design patternsDesign patterns
Design patternsdf
 

Ähnlich wie 120908 레거시코드활용전략 4장5장 (20)

About Visual C++ 10
About  Visual C++ 10About  Visual C++ 10
About Visual C++ 10
 
Domain Specific Languages With Groovy
Domain Specific Languages With GroovyDomain Specific Languages With Groovy
Domain Specific Languages With Groovy
 
Sonarqube 20160509
Sonarqube 20160509Sonarqube 20160509
Sonarqube 20160509
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
카사 공개세미나1회 W.E.L.C.
카사 공개세미나1회  W.E.L.C.카사 공개세미나1회  W.E.L.C.
카사 공개세미나1회 W.E.L.C.
 
Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005Working Effectively With Legacy Code - xp2005
Working Effectively With Legacy Code - xp2005
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기
 
함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
 
C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기C++ 프로젝트에 단위 테스트 도입하기
C++ 프로젝트에 단위 테스트 도입하기
 
C# Game Server
C# Game ServerC# Game Server
C# Game Server
 
Ai C#세미나
Ai C#세미나Ai C#세미나
Ai C#세미나
 
Spring Boot 2
Spring Boot 2Spring Boot 2
Spring Boot 2
 
Refactoring - Chapter 8.2
Refactoring - Chapter 8.2Refactoring - Chapter 8.2
Refactoring - Chapter 8.2
 
불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
 
Secrets of the JavaScript Ninja - Chapter 12. DOM modification
Secrets of the JavaScript Ninja - Chapter 12. DOM modificationSecrets of the JavaScript Ninja - Chapter 12. DOM modification
Secrets of the JavaScript Ninja - Chapter 12. DOM modification
 
Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택Boost라이브러리의내부구조 20151111 서진택
Boost라이브러리의내부구조 20151111 서진택
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storage
 
Design patterns
Design patternsDesign patterns
Design patterns
 

120908 레거시코드활용전략 4장5장

  • 1. 레거시 코드 활용 전략 4장 봉합 모델 5장 레거시 코드를 위한 도구 아꿈사 http://cafe.naver.com/architect1 최유림 http://blog.naver.com/sikyungelove
  • 2. 천공 카드 프로그래밍 • 데이터를 표현하기 위해 규칙에 따라 구멍을 뚫어 사용하는 종이 카드로서 초기의 저장매체 • 천공 위치에 구멍을 뚫거나 뚫지 않음으로서 하나의 비트를 나타날 수 있음 http://ko.wikipedia.org/wiki/%EC%B2%9C%EA%B3%B5_ %EC%B9%B4%EB%93%9C
  • 3. 봉합모델 레거시 코드를 위한 도구 정리가 안되지만 맞는 얘기들
  • 4. 봉합모델 레거시 코드를 위한 도구 정리가 안되지만 맞는 얘기들
  • 5. 봉합(Seams) • 프로그램 안에서 동작을 변화시킬 수 있는 위치 • 동작을 변화시키기 위해 코드를 편집할 필요는 없 음
  • 6. bool CAsyncSslRec::Init() { if(m_bSslInitialized){ return true; } m_smutex.Unlock(); m_nSslRefCount++; m_bSslInitialized = true; FreeLibrary(m_hSslDll1); m_hSslDll1 = 0; FreeLibrary(m_hSslDll2); •프로그램 안에서 동작을 변화시킬 수 있는 위치 m_hSslDll2 = 0; •동작을 변화시키기 위해 코드를 편집할 필요는 없음 if(!m_bFailureSent){ m_bFailureSent = true; PostReceiveError(SOCKETCALLBACK, SSL_FAILURE); } CreateLibrary(m_hSslDll1, "syncesel1.dll"); CreateLibrary(m_hSslDll2, "syncesel2.dll"); m_hSslDll2->Init(); m_hSslDll2->Init(); return true; }
  • 7. bool CAsyncSslRec::Init() { if(m_bSslInitialized){ return true; } m_smutex.Unlock(); m_nSslRefCount++; m_bSslInitialized = true; FreeLibrary(m_hSslDll1); m_hSslDll1 = 0; 동작을 변화시키지만 FreeLibrary(m_hSslDll2); 코드는 편집하지 않도록 함 m_hSslDll2 = 0; -> 코드와 테스트 분리 가능 if(!m_bFailureSent){ m_bFailureSent = true; PostReceiveError(SOCKETCALLBACK, SSL_FAILURE); } CreateLibrary(m_hSslDll1, "syncesel1.dll"); CreateLibrary(m_hSslDll2, "syncesel2.dll"); m_hSslDll2->Init(); m_hSslDll2->Init(); return true; }
  • 9. 봉합(Seams)의 종류 • 프로그래밍 언어에 따라 서로 다름 • 프로그램 텍스트가 시스템 코드로 변형되는 시점 에 따라 다름 • 컴파일 단계 : 전처리 봉합 • 링크 단계 : 연결 봉합 • 실행 단계 : 객체 봉합
  • 10. 전처리 봉합 • C, C++은 컴파일 하기 전에 매크로 전처리가 실 행됨
  • 11. • 전처리란 컴파일 전에 처리하는 매크로 • #로 시작 ex. #include <stdio.h> • 전처리기를 통하여 동작을 변화시키지만 코드는 편집하지 않도록 정의 • 많은 봉합의 기회 제공 • 전처리기 사용시 코드의 명료성이 떨어짐 • #define으로 정의되는 매크로는 단순히 텍스트 치환만 수행 • 불명확한 버그를 숨기기 위한 매크로를 만들기 쉬움
  • 12. bool CAsyncSslRec::Init() { if(m_bSslInitialized){ return true; } m_smutex.Unlock(); m_nSslRefCount++; m_bSslInitialized = true; FreeLibrary(m_hSslDll1); #include 문을 코드에 추가 m_hSslDll1 = 0; -> PostReceiveError 매크로 정의 FreeLibrary(m_hSslDll2); m_hSslDll2 = 0; -> 테스트용 전처리기 사용 if(!m_bFailureSent){ -> 전처리 봉합 m_bFailureSent = true; PostReceiveError(SOCKETCALLBACK, SSL_FAILURE); } CreateLibrary(m_hSslDll1, "syncesel1.dll"); CreateLibrary(m_hSslDll2, "syncesel2.dll"); m_hSslDll2->Init(); m_hSslDll2->Init(); return true; }
  • 13. 연결 봉합 • 링커는 컴파일러를 통해 만 들어진 여러 Object File들을 하나의 실행파일로 만듦 • C, C++은 독립된 링커 존재 • 자바는 링크 작업이 보이지 않음
  • 14. • 연결 봉합을 이용하는 가장 쉬운 방법은 바꾸고자 하는 클래스나 함수를 위해서 별도의 라이브러리를 만드는 것 • 테스트 해야 할 때 클래스나 함수 제작에 연결하지 않고, 새로 생성된 클래스나 함수에 연결되도록 빌드 스크립트를 변경하면 동작을 변화시키지만 코드는 편집하지 않음 • 제 3의 라이브러리를 호출하는 코드 베이스를 가진 경우 유용함
  • 15. bool CAsyncSslRec::Init() { if(m_bSslInitialized){ return true; } m_smutex.Unlock(); m_nSslRefCount++; m_bSslInitialized = true; PostReveiveError가 전역함수 FreeLibrary(m_hSslDll1); -> 라이브러리 생성 m_hSslDll1 = 0; -> 동작 제거를 위해 라이브러리 연결 FreeLibrary(m_hSslDll2); m_hSslDll2 = 0; -> 테스트 할때는 테스트 라이브러리와 연결 if(!m_bFailureSent){ -> 실제 시스템 빌드시, 제작 라이브러리와 연결 m_bFailureSent = true; PostReceiveError(SOCKETCALLBACK, SSL_FAILURE); } CreateLibrary(m_hSslDll1, "syncesel1.dll"); CreateLibrary(m_hSslDll2, "syncesel2.dll"); m_hSslDll2->Init(); m_hSslDll2->Init(); return true; }
  • 16. 객체 봉합 • 객체지향 프로그램은 어떤 메소드가 실행될지 정의하지 않음 • 같은 이름을 가지는 메소드가 하나 이상 있을 수 있음 • 주변 코드 변화 없이 어떤 메소드가 호출될지 변 경할 수 있는 경우가 객체 봉합
  • 17. bool CAsyncSslRec::Init() { if(m_bSslInitialized){ return true; } m_smutex.Unlock(); m_nSslRefCount++; m_bSslInitialized = true; PostReveiveError를 오버라이드 하는 FreeLibrary(m_hSslDll1); m_hSslDll1 = 0; 테스트용 하위 클래스 객체 생성 FreeLibrary(m_hSslDll2); -> 동작을 변화시키지만 m_hSslDll2 = 0; 코드는 편집하지 않도록 함 if(!m_bFailureSent){ m_bFailureSent = true; PostReceiveError(SOCKETCALLBACK, SSL_FAILURE); } CreateLibrary(m_hSslDll1, "syncesel1.dll"); CreateLibrary(m_hSslDll2, "syncesel2.dll"); m_hSslDll2->Init(); m_hSslDll2->Init(); return true; }
  • 18. 봉합모델 레거시 코드를 위한 도구 정리가 안되지만 맞는 얘기들
  • 19. 리팩토링 • 소프트웨어의 내부 구조에 가해지는 변화 • 소프트웨어에 존재하는 동작을 변경하지 않음 • 이해하기 쉽게 변경 • 직접 할 수도 있고, 도구를 이용 할 수도 있음
  • 20. 자동화된 리팩토링 도구 • 언어마다 리팩토링 도구들이 존재 • 통합개발 환경으로 구성되거나 분리됨
  • 21. 리팩토링 검증 • 리팩토링 과정에서 버그가 생길 수 있음 • 자동화된 리팩토링 도구에 버그가 있을 수 있음 • 리팩토링 후 동작을 변경시키지 않는지 검증해야 함
  • 22. 리팩토링 예제 public class A{ public class A{ private int alpha = 0; private int alpha = 0; private int getValue(){ private int getValue(){ alpha++; alpha++; return 12; return 12; } } public void doSomething(){ public void doSomething(){ int v = getValue(); int total = 0; int total = 0; for(int n=0; n<10; n++){ for(int n=0; n<10; n++){ total += getValue(); total += v; v를 제거하라!! } } } } } }
  • 23. 리팩토링 예제 public class A{ public class A{ private int alpha = 0; private int alpha = 0; private int getValue(){ private int getValue(){ alpha++; // alpha 1 증가 alpha++; // alpha 10 증가 return 12; return 12; } } public void doSomething(){ public void doSomething(){ int v = getValue(); int total = 0; int total = 0; for(int n=0; n<10; n++){ for(int n=0; n<10; n++){ total += getValue(); total += v; 리팩토링 후 } } 동작이 변경됨 } } } } 테스트 루틴을 두어 리팩토링 후 수행!! ex) alpha 값 검증
  • 25. xUnit 단위 테스트 프레임워크 • 소프트웨어의 함수나 클래스 같은 서로 다른 구성 원소(단위)를 테스트 하는 프레임워크 • 같은 테스트 코드를 여러번 작성하지 않음 • Java 단위 테스트는 jUnit C++ 단위 테스트는 CppUnit .NET 단위 테스트는 Nunit • 오픈소스로 사용 가능
  • 26. Junit • xUnit의 자바버전 • TestCase라는 클래스로 하위 클래스화함으로써 테스트 루틴을 작성
  • 27. import junit.framework.*; public class FormulaTest extends TestCase{ // testXXX() 형식의 메소드 public void testEmpty(){ // 테스트 하려는 내용(빈 경우 테스트) // 확인코드 // 코드포함가능(새로운 객체 생성, value 메소드 이용) assertEquals(0, new Formula("").value()); } public void testDigit(){ // 값이 일치하면 테스트 통과, 아니면 테스트 실패 assertEquals(1, new Formula("1").value()); } } 메소드 별로 서로 영향을 주지 않기 위해 각 테스트 메소드 용으로 완전히 분리된 객체 생성
  • 28. public class EmployeeTest extends TestCase{ private Employee employee; //테스트 메소드가 실행되기 전에 각 테스트 객체에서 실행됨 protected void setUp(){ //각 테스트에서 사용할 객체 생성 employee = new Employee("Fred", 0, 10); TDate cardDate = new TDate(10, 10, 2000); employee.addTimeCard(new TimeCard(cardDate, 40)); } public void testNormalPay(){ //setUp에서 생성된 하나의 employee가 한번만 시간카드의 봉급 계산하는지 검사 assertEquals(400, employee.getPay()); } public void testOvertime(){ TDate newCardDate = new TDate(11, 10, 2000); employee.addTimeCard(new TimeCard(newCardDate, 50)); //setUp에서 생성된 하나의 employee가 초과 근무 조건을 발생시키는지 검사 assertTrue(employee.hasOvertimeFor(newCardDate)); } }
  • 30. Fit • 통합 테스트 프레임워크 • 입력값, 출력값을 표로 작성 • HTML 형식으로 저장 • 작성한 표가 테스트 루틴이 됨 • 테스트를 통과하면 표의 셀을 녹색으로 표시 • 테스트를 실패하면 표의 셀을 빨간색으로 표시
  • 31. Fit • 고객(기획자)이 표를 작성 • 고객과 개발자 간의 의사소통이 쉬움 • 처음에는 모두 실패 • 개발 완료시, 테스트 모두 통과
  • 32. Fitnesse • 위키에 적용된 FIT • 빠르고 쉽고 테이블을 디자인 가능 • 웹 형태로 제공되어 누구나 쉽게 테스트케이스의 공유 및 작성, 테스트가 가능
  • 33. !define TEST_SYSTEM {slim} !define COLLAPSE_SETUP {true} !define COLLAPSE_TEARDOWN {true} !|Create Programs | |Name |Channel|DayOfWeek|TimeOfDay|DurationInMinutes|id? | |House|4 |Monday |19:00 |60 |$ID=|
  • 34. NTAF • 테스트 흐름이 획일적인 Fitnesse의 단점을 보완 • If, Loop, Parallel 등 키워드 추가 • 로그 확인, 변수 연산 등 가능
  • 35. 봉합모델 레거시 코드를 위한 도구 정리가 안되지만 맞는 얘기들
  • 36. 정리가 안되는 맞는 얘기들 • 재사용 가능하도록 작은 조각들로 쪼개 프로그램 을 작성하는 것이 좋음 • 자주 독립적으로 재사용되는 모듈화는 어려운 일 • 테스트하면 코드를 다른 각도에서 볼 수 있게 됨 • 테스트 루틴을 작성하려 할 때서야 기존의 코드가 얼마나 엉성하게 짜여져 있는지 알게 됨
  • 37. 비트 경제(?)와 공짜 테스트 나는 개발자 개발 해서 돈을 벌지~ 그런데 내가 왜 개발하면서 테스트 코드를 만들어야지? 테스트는 QA가 알아서 할텐데 뭣하러 공짜로?
  • 38. 공짜가 아니야~ 개발 단계에서 작성하는 테스트 코드는 QA가 진행하는 테스트보다 비용과 시간이 절감되지 기획과 합심하면 QA쯤이야 그 화폐를 우리 손으로~
  • 39. QA는 개발자가 할 수 없는 테스트를 찾아서..
  • 40. 레거시 코드 활용 전략 4장 봉합 모델 5장 레거시 코드를 위한 도구 감사합니다