Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

소프트웨어 설계 악취: 기술 부채 관리 방법

8.619 visualizaciones

Publicado el

"소프트웨어 악취를 제거하는 리팩토링: 구조적 설계 문제를 풀어내는 최선의 실천법" 책을 토대로 만든 세미나 자료

Publicado en: Software
  • People used to laugh at me behind my back before I was in shape or successful. Once I lost a lot of weight, I was so excited that I opened my own gym, and began helping others. I began to get quite a large following of students, and finally, I didn't catch someone laughing at me behind my back any longer. CLICK HERE NOW ♥♥♥ https://tinyurl.com/1minweight4u
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí

소프트웨어 설계 악취: 기술 부채 관리 방법

  1. 1. + 소프트웨어 설계 악취: 기술 부채 관리 방법 엑셈 CTO I 박재호(jaypark@ex-em.com)
  2. 2. + 목차 n  기술 부채 n  설계 악취 n  설계 원칙 n  악취에 대한 사례 연구: 추상화, 캡슐화, 모듈화, 계층화 n  깨끗한 코드
  3. 3. + 프로그램이 진화함에 따라 유지보수 작업을 행하거나 복잡도를 줄이지 않는 이상 프로그램의 복잡도는 증가한다. - 늘어나는 복잡도에 대한 레만의 법칙
  4. 4. + 부채 n  부채 n  미래의 부를 현재로 할인해서 당겨오는 행위로 인해 발생 n  부의 확장, 편의성 추구, 생존을 위한 지렛대로 사용할 수 있지만 기본적 으로는 최대한 작게 유지(risk!) n  이자 발생 n  상환 기간 n  복리 n  변동 금리 n  인플레이션
  5. 5. + 설계 악취와 기술 부채 n  설계 악취의 정의 n  설계 품질에 부정적인 영향을 미치고 기본 설계 원칙을 위반하는 설계상 의 특정 구조 n  설계 구조에서 잠재적인 문제 n  기술 부채의 정의 n  잘못되거나 최적화되지 않은 설계 결정을 의식적이거나 무의식적으로 내 릴 경우 축적되는 부채다 n  워드 커닝햄(1992)이 처음으로 사용 n  누적된 이자를 갚지 못하면 파산 à 기술 부채를 해소하지 못하면 제품 파산 n  코드 부채, 설계 부채, 테스트 부채, 문서 부채
  6. 6. + 기술 부채가 등장하는 이유? n  빨라진 제품 주기 n  경쟁사에 비해 더 빨리 더 저렴하게 시장에 신제품 출시 요구 n  설계 결정의 영향력을 적절히 평가할 기회나 시간적 여유 부족 n  지역적인 설계 결정의 집합이 구조적인 품질을 떨어뜨림 à 설계 부채 축 적 n  문제는 유지보수! n  기술 부채가 눈에 보이지 않는 이유? n  결함은 최종 사용자에게 직접 보임 n  기술 부채는 소프트웨어 시스템의 내부 품질에 영향을 미침 à 보이지 않 으므로 무시됨
  7. 7. + 기술 부채가 미치는 영향 n  기술 부채의 구성 요소 n  원금(꼼수나 지름길)과 이자(상환하지 않을 경우 치뤄야 할 대가) n  기술 부채에서 복리로 붙는 이자 문제 n  소프트웨어에 가해지는 새로운 변경이 부채에 허덕이는 설계 구조와 결 합해 부채를 더 늘이기 때문 à 더 많은 꼼수 à 더 많은 부채 n  변경 비용이 기술 부채에 따라 기하급수적으로 증가함 à 기술 파산 n  개발팀의 사기 저하 n  부채를 짊어진 3류 제품을 개발하고픈 개발자는 아무도 없다! n  단기간에 부채를 갚기란 쉽지 않기 때문 n  소프트웨어 변경을 시도할 경우 발생하는 불확실성과 위험에 직접 노출
  8. 8. +
  9. 9. + 기술 부채를 초래하는 원인 n  관리자, 아키텍트, 개발자들이 내린 엉뚱한 결정의 원인 n  일정 압력: 복사해붙이기 n  좋은/숙달된 설계자 부족: 악화(나쁜 관례)가 양화를 구축 n  설계 원칙의 응용 부족: 경험/인식 부족 n  설계 악취와 리펙터링에 대한 인식 부족 Programming == Googling stackoverflow?
  10. 10. + 기술 부채를 관리하는 방법 n  기술 부채에 대한 점진적인 자각 n  기술 부채의 감지와 상환 n  기술 부채의 누적 방지
  11. 11. + 설계 악취란? n  설계가 잘못되었음을 알려주는 징표 n  악취에 신경을 써야 하는 이유? n  소프트웨어 이해 가능성에 치명적인 문제를 일으킴 n  결함 수정과 개선을 위한 변경이 끊이지 않고 유지 보수 시간이 늘어남 n  논리적인 재사용이 불가함 n  안정성과 테스트 가능성이 점점 나빠짐 n  소프트웨어 설계가 소프트웨어 품질에 영향을 미침 n  설계가 잘못되면 악취가 발생!
  12. 12. + 악취가 영향을 미치는 품질 속성 n  소프트웨어 비기능 측면 n  이해 가능성 n  변경 가능성 n  확장 가능성 n  재사용 가능성 n  테스트 가능성 n  안정성 n  주의: 비기능은 소프트웨어의 내재된 속성이므로 개발자가 보증해 야 한다!
  13. 13. + 설계 악취를 일으키는 요인 n  설계 원칙 위반 n  부적절한 패턴 사용 n  언어 제약 n  객체지향에서 절차적인 사고 방식 n  점성 n  우수 관계와 우수 프로세스의 미준수
  14. 14. + 설계 악취를 일으키는 요인 n  java.util 패키지 일부인 Calendar 클래스 n  실세계의 달력 기능을 추상화 n  날짜와 관련된 기능을 제공 n  하지만 시간 관련 기능도 제공 n  여기서 위반된 설계 원칙 n  추상화는 유일한 책임만 맡아야 함 à 추상화 원칙 위반 n  다면적인 추상화 악취 발생 사례(설계 원칙 위반)
  15. 15. + 설계 악취를 일으키는 요인 n  JDK의 AbstractQueuedSynchronizer와 AbstractQueuedLongSynchronizer 클래스 n  두 클래스는 AbstractOwnableSynchronizer 에서 파생 n  원시 타입의 차이뿐! n  여기서 위반된 설계 원칙 n  펙터링이 안 된 설계 계층 악취 n  문제) 자바에서는 제네릭에서 원시 타입을 지원하지 않음! à 필연적인 코드 중첩 발생 사례(언어 제약)
  16. 16. + 설계 악취를 일으키는 요인 n  소프트웨어 점성이란? n  올바른 해법을 문제에 적용하는 과정에서 반드시 직면하는 저항(늘어나 는 노력과 시간) n  꼼수는 시간과 노력을 적게 요구(낮은 저항) n  환경 점성이란? n  우수 관례를 따르기 위해 반드시 극복해야 할 소프트웨어 개발 환경으로 인한 ‘저항’ n  우수 관계를 따를 때 시간이 더 많이 걸리면 나쁜 관례를 선택! n  개발 프로세스, 재사용 프로세스, 조직 요구 사항, 법적인 제약 사례(점성)
  17. 17. + 악취 분류에 기반한 설계 원칙 n  악취 맥락에서 위반이 일어난 설계 원칙을 인식할 필요가 있음 n  추상화 n  단순화와 일반화 기법을 사용해 엔티티의 단순화를 옹호함 n  단순화는 불필요한 세부 사항을 제거하며, 일반화는 공통적이며 중요한 특성을 파악 하고 명세함 n  캡슐화 n  추상화의 세부 구현과 변형을 숨기는 기법을 사용해 관심사 분리와 정보 은닉을 옹호 n  모듈화 n  지역화와 분해 기법을 사용해 응집력은 높고 결합력은 낮은 추상화 생성을 옹호 n  계층 구조 n  분류, 일반화, 대체, 배치와 같은 기법을 사용해 계층적인 추상화 구조 생성을 옹호
  18. 18. + 몇 가지 추가적인 설계 원칙(1) n  OCP(Open/Close Principle) n  모듈은 확장에 대해 열려야 하지만 변경에 대해 닫혀야 마땅하다 n  모듈은 코드 변경 없이 새로운 요구 사항을 지원할 수 있어야 마땅하다 n  단일 책임 원칙(SRP, Single Responsibility Principle) n  클래스가 변경되어야 하는 이유가 결코 둘 이상 있어서는 안 된다 n  각 책임은 변경 축이되므로, 각 변경은 단일 책임에만 영향을 미쳐야 마 땅하다 n  LSP(LISKOV’S SUBSTITUTION PRINCIPLE) n  상속 받은 클래스는 사용자가 차이점을 알 필요 없이 기초 클래스 인터페 이스를 통해 사용 가능해야만 한다
  19. 19. + 몇 가지 추가적인 설계 원칙(2) n  KISS(KEEP IT SIMPLE SILLY) 원칙 n  소프트웨어 설계 구성에는 두 가지 방법이 있다. 하나는 아주 단순하게 만들 어 명백하게 의존성이 하나도 없게 만드는 방법이며, 다른 하나는 아주 복잡 하게 만들어 명백한 의존성이 하나도 없게 만드는 방법이다 n  정보 은닉(Information Hiding) 원칙 n  어렵거나 변경되기 쉬운 설계 결정을 파악하고 적절한 모듈이나 타입을 생성 해 다른 모듈이나 타입으로부터 이런 결정을 감추는 방식 n  DRY(Don’t Repeat Yourself) 원칙 n  모든 지식은 시스템 내부에서 단일하고 모호하지 않고 권위 있는 표현이 되어 야만 한다 n  비순환 의존성 원칙(ADP, Acyclic Dependencies Principle) n  패키지 사이의 의존성은 순환을 형성해서는 안 된다
  20. 20. +
  21. 21. + 사례 연구 n  중복된 추상화 악취란? n  이름이 같거나 구현이 동일하거나 이름도 같고 구현도 동일할 때 발생하 는 악취 n  동일한 이름: 추상화 이름이 동일(우연히 이름이 동일할 가능성에 주 의!) n  동일한 구현: 의미상으로 동일한 멤버 정의가 있는 경우 n  문제의 원인: DRY, 중복 방지 원칙을 어김(예: 복붙) n  여파: 코드 중복으로 인한 유지보수가 어려워짐 추상화 악취 중 중복된 추상화
  22. 22. + 사례 연구 n  예제: JDK에 존재하는 이름이 동일한 클래스 n  자바 7에서 4005개 타입 중 135개 타입이 중복(3.3%)! n  예: java.util.Date와 여기서 파생된 java.sql.Date 클래스 n  컴파일러가 문제 삼지 않는 이유 n  패키지가 다르다 n  사용자 입장에서 문제가 되는 이유 n  두 클래스를 동시에 import할 경우 명시적으로 한정해야 한다 à 모호성 문제를 수동으로 해소 추상화 악취 중 중복된 추상화
  23. 23. + 사례 연구 n  리펙터링 제안 n  java.sql.Date JavaDoc 문서: “SQL DATE 정의에 순응하기 위해, java.sql.Date 인스턴스가 감싼 밀리 초 값은 관련된 인스턴스가 위치한 특정 시간대에 맞춰 시, 분, 초, 밀리 초를 0으로 설정하는 방식으로 ‘정규화되어야’만 한다.” n  더 나은 설계안 n  java.sql.Date에서 java.util.Date 인스턴스를 감싸기 n  상속을 위임으로 변환 n  또한 java.sql.SQLDate로 이름 변경 추상화 악취 중 중복된 추상화
  24. 24. + 사례 연구 n  누락된 캡슐화 악취란? n  구현 변형을 계층 내부나 추상화 내부에서 캡슐화하지 않을 경우 발생하 는 악취 n  문제의 원인: OCP 위반(타입의 행동 양식은 변경이 아니라 확장에 의해 바꿔야 함) n  여파: 계층에 새로운 변형을 지원하려고 시도할 때마다 불필요한 클래스 ‘폭발’ 발생 캡슐화 악취 중 누락된 캡슐화
  25. 25. + 사례 연구 n  예제(1) n  데이터 암호화를 위한 Encryption 클래스: DES (Data Encryption Standard), AES (Advanced Encryption Standard), TDES (Triple Data Encryption Standard)를 포함해 알고리즘에 대한 다양한 선택이 가능 n  초보 개발자는 Encryption 클래스 내부에 EncryptUsingDES(), EncryptiUsingAES(), …와 같은 수많은 메소드를 추가 n  문제점 n  Encryption 클래스가 알고리즘 추가에 따라 점점 커짐(한번에 알고리즘 을 하나만 사용하더라도 덩치 큰 클래스를 가져와야 함) n  새로운 알고리즘 추가가 어려움 n  특정 알고리즘 하나만 재사용하기가 불가능 캡슐화 악취 중 누락된 캡슐화
  26. 26. + 사례 연구 n  예제(2) n  데이터 암호화를 위한 알고리즘 뿐만 아니라 다양한 유형의 데이터를 암 호화 n  내용 유형과 암호화 알고리즘 유형의 두 가지 변형이 존재 n  DESImageEncryption, AESTextEncryption, … n  문제점 n  구현에서 변형이 서로 뒤섞이며, 독자적으로 캡슐화되지 못함 n  클래스 폭발로 마무리 캡슐화 악취 중 누락된 캡슐화
  27. 27. + 사례 연구 n  리펙터링 제안 n  예제(1) n  EncryptionAlgorithm 인터페이스를 생성 n  DESEncryptionAlgorithm와 AESEncryptionAlgorithm는 EncryptionAlgorithm 인터페이스를 구현하고 각각 DES와 AES 알고 리즘을 정의 n  Encryption 클래스는 EncryptionAlgorithm 인터페이스에 대한 참조 를 유지 n  장점 n  Encryption 객체는 실행 시간에 특정 암호화 알고리즘으로 구성 가능 n  EncryptionAlgorithm 계층에 정의된 알고리즘은 다른 맥락에서 재사 용 가능 n  새로운 알고리즘 추가 용이 캡슐화 악취 중 누락된 캡슐화
  28. 28. + 사례 연구 캡슐화 악취 중 누락된 캡슐화 깨진 계층화 악취 다른 맥락에서 알고리즘 재사용 불가
  29. 29. + 사례 연구 n  리펙터링 제안 n  예제(2) n  두 가지 직교적인 관심사에 대해 독자적으로 변형을 캡슐화 캡슐화 악취 중 누락된 캡슐화
  30. 30. + 사례 연구 n  불충분한 모듈화 악취란? n  완벽하게 분해되지 않은 추상화 à 추가로 분해할 경우 크기/구현 복잡도 해소 가능 n  부풀어로은 인터페이스: 추상화의 공개 인터페이스에 엄청나게 많은 멤버 존재 n  부풀어오른 구현: 구현에 엄청나게 많은 메소드 존재/구현 복잡도가 과 도하게 높은 메소드가 하나 이상 존재 n  문제의 원인: 추상화를 관리 가능한 크기로 유지하지 못함 n  ‘연산과 클래스는 조화로운 크기가 되어야 마땅하다. 다시 말해, 크기 는 양극단을 피해야 마땅하다.” n  주의: SRP와 혼동 à 책임이 하나인 추상화면서도 여전히 크고 복잡할 수 있다. 유사하게, 작은 추상화면서도 여전히 책임이 여럿일 수 있다 모듈화 악취 중 불충분한 모듈화
  31. 31. + 사례 연구 n  불충분한 모듈화 악취란? n  완벽하게 분해되지 않은 추상화 à 추가로 분해할 경우 크기/구현 복잡도 해소 가능 n  부풀어로은 인터페이스: 추상화의 공개 인터페이스에 엄청나게 많은 멤버 존재 n  부풀어오른 구현: 구현에 엄청나게 많은 메소드 존재/구현 복잡도가 과 도하게 높은 메소드가 하나 이상 존재 n  문제의 원인: 추상화를 관리 가능한 크기로 유지하지 못함 n  ‘연산과 클래스는 조화로운 크기가 되어야 마땅하다. 다시 말해, 크기 는 양극단을 피해야 마땅하다.” n  주의: SRP와 혼동 à 책임이 하나인 추상화면서도 여전히 크고 복잡할 수 있다. 유사하게, 작은 추상화면서도 여전히 책임이 여럿일 수 있다. 모듈화 악취 중 불충분한 모듈화
  32. 32. + 사례 연구 n  예제: JDK에 존재하는 java.awt.Component 클래스 n  메소드가 332개(그 중 259개가 public으로 선언!) n  중첩된 내부 클래스가 11개, 필드가 107개(상수 포함) n  원시 코드: 10,102행 n  문제점 n  분석, 유지보수, 기능 추가 과정에서 이 클래스를 이해하기가 너무 복잡 하다! 추상화 악취 중 중복된 추상화
  33. 33. + 사례 연구 n  리펙터링 방안 n  부풀어오른 인터페이스 n  공개 인터페이스의 부분 집합이 밀접히 연관된 (응집력이 높은) 멤버를 포 함하면, 부분 집합을 독자적인 추상화로 추출 n  클래스가 멤버로 구성된 부분 집합을 둘 이상 포함하며 각 부분 집합의 응 집력이 높으면, 이런 부분 집합을 독자적인 클래스로 나눔 n  클래스 인터페이스가 클라이언트에 밀접한 메소드를 사용해 여러 클라이 언트를 서비스하면, 원본 인터페이스를 클라이언트에 밀접한 여러 인터페 이스로 분리하기 위해 ISP(Interface Segregation Principle)를 적용 n  부풀어오른 구현 n  메소드 논리가 복잡하면, 해당 메소드에 있는 코드를 단순하게 만들기 위 해 사적인 도우미 메소드를 도입 n  불충분한 모듈화 악취와 함께 다면적인 추상화 악취까지 포함하는 추상화 라면, 각 책임을 분리된 (새로 만들거나 기존에 존재하는) 추상화에 캡슐화 추상화 악취 중 중복된 추상화
  34. 34. + 사례 연구 n  넓은 계층 악취란? n  중간 타입이 빠졌을지도 모른다는 사실을 암시하는 ‘너무’ 넓은 상속 관계 가 존재하는 악취 n  문제의 원인: ‘의미있는 일반화 적용’이라는 요소 기술을 위반 n  빠진 중간 타입은 계층에 있는 클라이언트가 하위 타입을 직접 참조하 게 강제할지도 모른다. 이런 의존성은 계층의 변경 가능성과 확장 가능 성에 영향을 미친다. n  타입 내부에 불필요한 중복이 있을지도 모른다(중간 타입의 부족으로 인해 공통성을 적절히 추상화할 수 없다) n  영향: 동일 층에 하위 타입 수가 너무 많으면(9개를 넘길 경우), 계층을 이해하거나 사용하기가 더 어려워짐 계층 악취 중 넓은 계층
  35. 35. + 사례 연구 n  예제 n  JDK 7에서 바로 아래 하위 클래스 36개를 거느리는 java.util.EventObject 클래스 n  문제점 n  형제자매 클래스가 엄청나게 많아서 이해가 어려움 계층 악취 중 넓은 계층
  36. 36. + 사례 연구 n  리펙터링 제안 n  중간 타입을 도입 n  예: TreeEvent 계층 악취 중 넓은 계층
  37. 37. + 설계에서 코드로 n  설계 리펙터링은 코드 리펙터링과 밀접한 관련이 있다! n  깨끗한 설계를 유지하는 동시에 깨끗한 코드를 유지해야 한다
  38. 38. + 참고 자료
  39. 39. +

×