소프트웨어 공학/Theorem

[소프트웨어 공학] 09. Software Evolution

lumana 2024. 5. 10. 16:59

Software Evolution


Software change (소프트웨어 변경)

  • 소프트웨어 변경은 필연적입니다.
    • 소프트웨어를 사용할 때 새로운 요구사항(requirements)이 생겨납니다.
    • 비즈니스 환경(business environment)이 변합니다;
    • 오류(errors)는 수정되어야 합니다;
    • 시스템에 새로운 컴퓨터(computers)와 장비(equipment)가 추가됩니다;
    • 시스템의 성능(performance) 또는 신뢰성(reliability)이 향상되어야 할 수 있습니다.
  • 모든 조직에 있어 기존 소프트웨어 시스템에 대한 변경을 구현하고 관리하는 것이 주요 문제입니다.

Importance of evolution (진화의 중요성)

  • 조직은 소프트웨어 시스템에 큰 투자를 합니다 - 그것들은 중요한 비즈니스 자산(business assets)입니다.
  • 이 자산들의 가치를 유지하기 위해, 그것들은 변경되고 업데이트되어야 합니다.
  • 소프트웨어 예산의 대부분은 새 소프트웨어를 개발하는 것이 아니라 기존 소프트웨어를 변경하고 진화시키는 데 사용됩니다.
    • 소프트웨어 디버깅(debugging)만 해도 개발자들의 상당한 시간을 차지합니다.
    • 미국 개발자들은 소프트웨어 디버깅에 시간의 35%를 소비합니다.
    • 또 다른 연구에 따르면 디버깅은 약 50%의 시간을 차지하며, 소프트웨어 버그(software bugs)로 인한 비용은 연간 3120억 달러에 달합니다.

Evolution and servicing (진화와 서비스)

  • 시간에 따른 소프트웨어의 단계: 개발(development), 진화(evolution), 서비스(servicing), 퇴출(retirement).

A spiral model of development and evolution (개발 및 진화의 나선형 모델)

  • 나선형 모델에서는 명세(specification), 구현(implementation), 운영(operation), 검증(validation) 단계가 반복됩니다.

The software evolution process (소프트웨어 진화 과정)

  • 변경 요청(change requests)에서부터 영향 분석(impact analysis), 출시 계획(release planning), 변경 구현(change implementation), 시스템 출시(system release)로 이어지는 과정입니다.

Change implementation (변경 구현)

  • 개발 과정의 반복으로, 시스템의 수정이 설계, 구현 및 테스트됩니다.
  • 초기 단계에서는 프로그램 이해(program understanding)가 포함될 수 있으며(the first stage of change implementation may involve program understanding), 원래 시스템 개발자가 변경 구현을 담당하지 않는 경우가 많습니다.
  • 프로그램 이해 단계에서는 프로그램의 구조, 기능성, 제안된 변경이 프로그램에 미칠 영향(proposed change might affect the program)을 이해해야 합니다.

Agile methods and evolution (애자일 방법론과 진화)

  • 애자일 방법론(agile methods)은 점진적 개발에 기반을 두고 있어 개발에서 진화로의 전환은 매끄러운 것입니다.
    • 진화는 개발 과정의 지속적인 반복으로(Evolution is simply a continuation of the development process), 자주 시스템 출시를 기반으로 합니다.
  • 연속 통합(continuous integration) 동안 자동 회귀 테스트(automated regression testing)가 수행되며, 시스템에 변경이 이루어질 때 특히 가치가 있습니다.
  • 변경 사항은 추가적인 사용자 스토리(user stories)로 표현될 수 있습니다.

Legacy systems (레거시 시스템)

  • 레거시 시스템(Legacy systems)은 새로운 시스템에 사용되지 않는 언어와 기술에 의존하는 오래된 시스템(older systems)입니다.
    • e.g) Y2K issues and COBOL, Dismissal of ActiveX, Flash.
  • 레거시 소프트웨어는 종종 더 오래된 하드웨어에 의존하며, 관련 레거시 프로세스와 절차가 있을 수 있습니다.
  • 레거시 시스템은 소프트웨어 시스템뿐만 아니라(Legacy systems are not just software systems) 하드웨어, 라이브러리 및 기타 지원 소프트웨어, 비즈니스 프로세스를 포함한 더 넓은 사회 기술 시스템(but are boarder socio-technical systems)입니다.

Legacy system components (레거시 시스템 구성 요소)

  • System hardware(시스템 하드웨어): 레거시 시스템은 더 이상 사용할 수 없는 하드웨어용으로 작성되었을 수 있습니다.
  • Support software(지원 소프트웨어): 레거시 시스템은 더 이상 사용되지 않거나 지원되지 않을 수 있는 다양한 지원 소프트웨어에 의존할 수 있습니다.
  • Application software(응용 소프트웨어): 비즈니스 서비스를 제공하는 응용시스템은 일반적으로 다수의 응용프로그램으로 구성된다.
  • Application data(애플리케이션 데이터): 애플리케이션 시스템에서 처리되는 데이터입니다. 일관성이 없거나 중복되거나 다른 데이터베이스에 보관될 수 있습니다.
  • Business processes(비즈니스 프로세스): 일부 비즈니스 목표를 달성하기 위해 비즈니스에서 사용되는 프로세스입니다.
    • 비즈니스 프로세스는 레거시 시스템을 중심으로 설계되었으며 레거시 시스템이 제공하는 기능에 의해 제한될 수 있습니다.
  • Business polices and rules(비즈니스 정책 및 규칙): 비즈니스를 수행하는 방법과 비즈니스에 대한 제약 사항에 대한 정의입니다.
    • 레거시 애플리케이션 시스템의 사용이 이러한 정책 및 규칙에 포함될 수 있습니다.

Legacy system replacement (레거시 시스템 교체)

  • 레거시 시스템 교체는 위험(risky)하고 비용이 많이 드는(expensive) 일이므로 기업들은 이 시스템을 계속 사용하고 있습니다.
  • 시스템 교체는 다음과 같은 여러 가지 이유로 위험합니다.
    • 완전한 시스템 사양(system specification)이 부족
    • 시스템과 비즈니스 프로세스(business processes)의 긴밀한 통합
    • 레거시 시스템에 내장된 문서화되지 않은 비즈니스 규칙(undocumented business rules)
    • 새 소프트웨어(new software) 개발이 지연되거나 예산을 초과할 수 있음

Legacy system change (레거시 시스템 변경)

  • 레거시 시스템은 변경하기에 비용이 많이 들고(expensive) 다음과 같은 여러 이유로 인해 어렵습니다:
    • 일관되지 않은 프로그래밍 스타일(inconsistent programming style).
    • 사용되지 않는 프로그래밍 언어(obsolete programming languages) 사용, 해당 언어를 다룰 수 있는 사람이 적음.
    • 불충분한 시스템 문서화(inadequate system documentation).
    • 시스템 구조의 저하(system structure degradation).
    • 프로그램 최적화(program optimizations)로 인해 이해하기 어려움.
    • 데이터 오류(data errors), 중복(duplication), 불일치(inconsistency).

Legacy system management (레거시 시스템 관리)

  • 레거시 시스템에 의존하는 조직은 이 시스템을 진화시키기 위한 전략을 선택해야 합니다.
    • 시스템을 완전히 폐기(Scrap)하고 비즈니스 프로세스를 수정하여 더 이상 필요하지 않게 함.
    • 시스템을 계속 유지(maintaining)함.
    • 시스템을 재공학(re-engineering)하여 유지 관리성(maintainability)을 향상시킴.
      • Transfrom the system by re-engineering to improve its maintainability
    • 새 시스템으로 교체(Replace)함.

An example of a legacy system assessment (레거시 시스템 평가 예)

  • 선택된 전략은 시스템의 품질(system quality)과 비즈니스 가치(business value)에 따라 달라야 합니다.

Legacy system categories (레거시 시스템 분류)

시험에 나올 수 있는 부분이니 주의 깊게 보자

  • 낮은 품질(low quality), 낮은 비즈니스 가치(low business value)
    • 이러한 시스템은 폐기되어야 합니다.
  • 낮은 품질, 높은 비즈니스 가치(high business value)
    • 중요한 비즈니스 기여를 하지만 유지 관리 비용이 많이 든다
    • 적합한 시스템이 있을 경우 재공학(re-engineered)하거나 교체해야 합니다.
  • 높은 품질(high quality), 낮은 비즈니스 가치(Low-business value)
    • COTS로 교체하거나 완전히 폐기하거나 유지 관리합니다.
  • 높은 품질(high quality), 높은 비즈니스 가치(High business value)
    • 정상적인 시스템 유지 관리를 사용하여 계속 운영합니다.

Business value assessment (비즈니스 가치 평가)

  • The use of the system(시스템 사용)
    • 시스템이 가끔이나 소수의 사람들에 의해서만 사용된다면, 비즈니스 가치가 낮을 수 있습니다.
  • The business processes that are supported(지원되는 비즈니스 프로세스)
    • 시스템이 비효율적인 비즈니스 프로세스를 강제한다면 비즈니스 가치가 낮을 수 있습니다.
  • 시스템 의존성(system dependability)
    • 시스템이 믿을 수 없고 그 문제가 비즈니스 고객에게 직접적인 영향을 미친다면 비즈니스 가치가 낮습니다.
  • 시스템 출력(system outputs)
    • 비즈니스가 시스템 출력에 의존한다면, 시스템은 높은 비즈니스 가치를 가집니다.
    • 이 시스템이 우리에게 출력하고 있는게 무엇인가?

System quality assessment (시스템 품질 평가)

System quiality --> 이거 3개 기준으로 평가하자

  • 비즈니스 프로세스 평가(business process assessment)
    • 비즈니스 프로세스가 비즈니스의 현재 목표를 얼마나 잘 지원하는지?
    • 불필요한 것 때문에 비즈니스 프로세스가 방해받지 않아야 함
  • 환경 평가(environment assessment)
    • 시스템 환경이 얼마나 효과적이며 유지 관리하는 데 얼마나 비용이 드는지?
    • ex) 티켓팅 시스템의 서버
  • 응용 프로그램 평가(application assessment)
    • 응용 소프트웨어 시스템의 품질은 어떠한가?
    • 우리가 작성한 코드 자체가 얼마나 깔끔한가? 외부 라이브러리는 어떻게 사용하고 있는가? 보안은?...

Software maintenance (소프트웨어 유지 관리)

실제로 사용자에게 전달해서 사용하고 있을 때, 버그를 고치는 등의 maintenance를 말함(만들어서 전달하는 SW에 대한 maintenance)

  • 사용된 후 프로그램을 수정하는 것.
  • 이 용어는 주로 맞춤형 소프트웨어(custom software) 변경에 사용됩니다.
    • 일반 소프트웨어 제품은 새로운 버전을 만들기 위해 진화한다고 말해집니다.
  • 유지 관리는 일반적으로 시스템의 주요 구조 변경을 포함하지 않습니다.
    • 소소하게 바꾸지, 다 뜯어고치지 않는다
  • 변경은 시스템에 존재하는 구성 요소를 수정하거나 새로운 구성 요소를 추가함으로써 구현됩니다.
    • 시스템 아키텍처는 유지되는 상황에서 무언가가 추가됨

Types of maintenance (유지 관리 유형)

  • 결함 수리(fault repairs)
    • 버그/취약점을 수정하고 요구사항을 충족하는 방식에서의 결함을 수정하여 시스템을 변경합니다.
  • 환경 적응(environmental adaptation)
    • 소프트웨어를 다른 운영 환경으로 적응시키기 위한 유지 관리입니다.
    • 초기 구현과 다른 환경(컴퓨터, OS 등)에서 작동하도록 시스템을 변경하는 것입니다.
  • 기능 추가 및 수정(functionality addition and modification)
    • 새로운 요구사항을 충족시키기 위해 시스템을 수정합니다.
    • System enhancement에 해당하는 유형

Maintenance Effort Distribution (유지 관리 노력 분배)

  • 결함 수리(Fault repair): 24%
  • 환경적응(Environmental adaptation): 19%
  • 기능 추가 또는 수정(Functionality addition or modification): 58%
    • 애자일에서 자연스럽게 일어나는 과정임

Maintenance Costs (유지 관리 비용)

  • 개발 비용보다 훨씬 높음 (애플리케이션에 따라 2배에서 100배).
  • 기술적 및 비기술적 요인에 의해 영향을 받음.
  • 소프트웨어가 유지 관리됨에 따라 증가함.
    • 유지 관리는 소프트웨어 구조를 손상시켜 추가 유지 관리를 더 어렵게 만듦.
    • 개발하다 보면 구조가 복잡해짐 --> 비용 증가
  • 노화된 소프트웨어는 높은 지원 비용을 초래할 수 있음 (예: 구식 언어, 컴파일러 등).
    • 오래된 SW일수록 비용 증가
    • ex) ajax --> jquery --> nodejs, react

Software Reengineering (소프트웨어 재공학)

  • 레거시 시스템의 일부 또는 전체를 재구조화하거나 다시 작성하여 기능을 변경하지 않음.
    • 기능은 그대로 두고, maintenability를 올리기 위해 Reengineering을 한다
    • Refacoring 보다 큰 개념임
  • 일부 하위 시스템이 자주 유지 관리가 필요한 큰 시스템에 적용 가능.
  • 재공학은 유지 관리를 용이하게 하기 위해 노력을 추가함.
    • 시스템은 재구조화되고 재문서화될 수 있음.

Advantages of Reengineering (재공학의 장점)

  • Reduced risk(위험 감소)
    • 새로운 소프트웨어 개발에서는 높은 위험이 있음.
    • development problems, staffing problems and specification problems 가 있을 수 있다
  • Reduced cost(비용 감소)
    • 재공학 비용은 종종 새로운 소프트웨어 개발 비용보다 훨씬 적음.

Reengineering Process Activities (재공학 과정 활동)

  • 소스 코드 변환(Source code translation)
    • 코드를 새로운 언어로 변환.
  • 역공학(Reverse engineering)
    • 프로그램을 분석하여 이해.
  • 프로그램 구조 개선(Program structure improvement)
    • 이해를 돕기 위해 자동으로 구조를 재구성.
    • ex) 모듈화
  • 프로그램 모듈화(Program modularisation)
    • 프로그램 구조를 재정리.
  • 데이터 재공학(Data reengineering)
    • 시스템 데이터를 정리하고 재구조화.
    • Application data도 Legacy에서 중요한 컴포넌트임. 이 data를 새로운 format으로 바꿨는데 사용에 문제가 있다면 정리해주거나, 삭제하거나, 재구조화 해준다

Refactoring (리팩토링)

  • 프로그램에 개선을 통해 변화에 따른 퇴화를 늦추는 과정.
  • 리팩토링은 예방 유지 보수(preventative maintenance)로 생각할 수 있으며, 미래 변화의 문제를 줄임.
  • 리팩토링은 프로그램의 구조를 개선하고 복잡성을 줄이며 이해를 쉽게 하기 위해 프로그램을 수정함.
  • 리팩토링할 때 기능을 추가하는 것이 아니라 프로그램 개선에 집중해야 함.(you should not add functionality but rather concentrate on program improvement)
    • Root Canal vs Floss Refactoring
      • 이를 가는 것 vs 치실 
      • 치실은 매일 사용 --> 자잘한 작업 
      • Root Canal : 큰 작업, 자잘한 작업으로 커버가 안됨 

Refactoring and Reengineering (리팩토링 및 재공학)

  • 재공학은 시스템이 유지 보수되어 오랜 시간 동안 유지 관리 비용이 증가한 후에 이루어짐.
    • 크게 한 번 갈아 엎는 것, automated tool의 도움을 많이 받음 
    • 자동화 도구를 사용하여 처리하고 레거시 시스템을 재공학하여 더 유지 관리하기 쉬운 새 시스템을 만듦.
  • 리팩토링은 개발 및 진화 과정 전반에 걸쳐 지속적인 개선 과정임.
    • automated tool을 잘 쓰지 않는 경향이 있음(원하는 대로 잘 안되서)
    • 구조 및 코드의 퇴화를 방지하여 유지 관리 비용과 어려움을 증가시키는 것을 목표로 함.

‘Bad smells’ in program code (프로그램 코드의 ‘나쁜 냄새’)

  • 중복 코드(Duplicate code, 일명 코드 클론(Code Clones)):
    • 프로그램의 다양한 장소에서 동일하거나 매우 유사한 코드가 포함될 수 있습니다. 이는 제거되고 필요에 따라 호출되는 단일 메소드나 함수로 구현될 수 있습니다.
    • Code Clones : 중복된 코드가 문제가 되는 경우가 많음 (버그가 복사된다던지 등등)
    • 비슷한 코드가 여러 군데에 흩어져 있는 상황을 예로 들 수 있다.
      • 위의 경우 하나의 함수로 만들어 주는 방식 등으로 해결할 수 있다.
  • 긴 메소드(Long methods)
    • 메소드가 너무 길면, 여러 개의 더 짧은 메소드로 재설계될 수 있습니다.
    • 메서드 하나가 엄청나게 긴 경우(modularity가 낮음) 메서드 하나를 private 메서드로 분리할 수 있다.
      • private 메서드에 비해 public 메서드는 더 신경 써줘야 한다.
  • 스위치 문(Switch (case) statements)
    • 이들은 종종 중복을 포함하며, 스위치 문은 값의 유형에 따라 달라집니다.
    • switch 문은 프로그램 전반에 scattered 되어 있을 수 있다. 객체 지향 언어에서는 동일한 기능을 달성하기 위해 다형성을 사용할 수 있습니다.
    • 언제 if-else를 쓰고 Switch를 쓸 건지, 아니면 다른 방식으로 처리할 건지
  • 데이터 뭉치(Data clumping)
    • 동일한 데이터 항목 그룹(필드, 메소드의 매개변수)이 프로그램의 여러 곳에서 반복됩니다.
    • 이들은 종종 모든 데이터를 캡슐화하는 객체로 대체될 수 있습니다.
    • ex)
    • method1(int[] block, Block currBlock), method2(int[] block, Block currBlock), method(int[] block, Block currBlock)
    • --> 파라미터를 Board 클래스로 뽑아서, 클래스 인스턴스를 파라미터로 설정한다
  • 추측적 일반성(Speculative generality)
    • 개발자가 미래에 필요할 수 있는 일반성을 프로그램에 포함시키는 경우입니다.
    • 이는 종종 간단히 제거될 수 있습니다.
    • 과연 이걸 specific하게 작성하면 나중에 새로운 기능을 추가할 때 이 부분의 작업이 증가하지 않을까?
    • 너무 generality를 높이면 오히러 작업 시간이 증가하고, 구조가 안좋아질 수 있다.

 

실제 코드 refactoring 예시

  • IDE의 Refactor -> Rename 기능 사용하여 명확한 identifer 이름 사용
  • IDE extract method 기능으로 모듈화
  • 이너 클래스를 다른 파일로 추출
    • 이렇게 modulization을 함으로써 메서드가 어떤일을 하는지 확인할 수 있는 가독성도 늘어나고, 코드 라인도 줄어듬