몇 년 동안 크고 복잡한 소프트웨어 제품을 유지 관리하는 방법?


156

저는 수년 동안 소프트웨어 개발자로 일해 왔습니다. 더 많은 개발자가 제품 개발에 참여함에 따라 프로젝트가 더 복잡하고 유지 관리 할 수없는 경험이 있습니다.

특정 개발 단계의 소프트웨어는 특히 아키텍처를 정의한 팀 구성원이 회사에서 더 이상 작업하지 않는 경우 "해커"및 "해커"를 얻는 경향이있는 것 같습니다.

무언가를 변경해야하는 개발자가 아키텍처의 큰 그림을 얻는 데 어려움을 겪고 있다는 것이 실망 스러웠습니다. 따라서 원래 아키텍처와는 다른 방식으로 문제를 해결하거나 변경하는 경향이 있습니다. 결과적으로 코드가 점점 더 복잡해지고 이해하기가 더 어려워집니다.

몇 년 동안 소스 코드를 실제로 유지 관리하는 방법에 대한 유용한 조언이 있습니까?


9
높은 책을 추천 : 마틴 파울러 스티브 맥코넬에 의해 스티브 맥코넬, '신속한 개발'에 의한 '소프트웨어 프로젝트 생존 가이드', '리팩토링을'
이므 란 오마르 Bukhsh

15
... 그리고 Uncle Bob의 'Clean Code';) (Robert C. Martin)
Gandalf

34
이것은 대학에서 수십 년에 걸친 많은 양의 독서와 전체 과정을 일으킨 질문이 아닌가?
detly

17
@ 에릭 음-나는 의견에 동의하지 않습니다. 나에게는 그것들이 코드 냄새이고 장기 프로젝트에서 필연적으로 데이트를하고 오도하기 때문에 좋은 것보다 더 해로운 경향이 있습니다.
JohnFx

8
@Eric Yin : 자체 문서화 코드를 위해 노력합니다. 이해를 높이는 경우에만 의도에 대한 의견을 사용하십시오.
Mitch Wheat

답변:


138

코드 부패를 피하는 유일한 해결책은 코드를 잘 작성하는 것입니다!

잘 코딩하는 방법은 또 다른 질문입니다. 혼자 일하는 훌륭한 프로그래머라도 힘들다. 이기종 팀에서는 여전히 더 어려워집니다. 아웃소싱 된 (하위) 프로젝트에서 ... 그냥기도하십시오.

일반적인 모범 사례가 도움이 될 수 있습니다.

  1. 간단하게 유지하십시오.
  2. 간단하게 유지하십시오. 이것은 특히 "큰 그림"이라는 아키텍처에 적용됩니다. 개발자가 큰 그림을 얻는 데 어려움 겪고 있다면 그것에 대해 코드를 작성하려고합니다. 따라서 모든 개발자가 얻을 수 있도록 아키텍처를 단순하게 만드십시오. 아키텍처가 단순하지 않은 경우 개발자는 해당 아키텍처를 이해하도록 교육을 받아야합니다. 내부화하지 않으면 코드화해서는 안됩니다.
  3. 낮은 커플 링높은 응집력을 목표로합니다 . 팀의 모든 사람들이이 아이디어를 이해하도록하십시오. 느슨하게 결합 된 점착성 부품으로 구성된 프로젝트에서 일부 부품이 유지 보수가 어려워지면 해당 부품을 분리했다가 다시 쓸 수 있습니다. 커플 링이 빡빡하면 힘들거나 거의 불가능합니다.
  4. 일관성을 유지하십시오. 어떤 문제가 좀 따라,하지만 따라 마십시오 표준 몇 가지 기준을. 팀에서 모든 사람은 물론 동일한 표준을 따라야합니다. 반면에 표준에 너무 쉽게 붙들어 나머지는 잊어 버리기 쉽습니다. 표준은 유용하지만 좋은 코드를 만드는 데있어 작은 부분 일뿐입니다. 많이 만들지 마십시오.
  5. 코드 검토 는 팀이 일관되게 작업하는 데 유용 할 수 있습니다.
  6. IDE, 컴파일러, 버전 제어, 빌드 시스템, 문서 생성기, 라이브러리, 컴퓨터 , 의자 , 전체 환경 등의 모든 도구 를 잘 관리하여 개발자가 2 차 문제로 시간을 낭비하지 않도록하십시오. 프로젝트 파일 버전 충돌, Windows 업데이트, 소음 및 독특하지만 자극적 인 내용과 싸우는 것. 그런 흥미롭지 않은 물건으로 많은 시간을 반복적으로 낭비해야 사기가 낮아져 최소한 코드 품질이 향상되지는 않습니다. 대규모 팀에는 개발자 도구를 유지 관리하는 일을하는 사람이 한 명 이상있을 수 있습니다.
  7. 기술 결정을 내릴 때 기술을 전환하는 데 무엇이 필요할지 생각하십시오. 돌이킬 수없는 결정과 그렇지 않은 결정 돌이킬 수없는 결정을 더 신중하게 평가하십시오. 예를 들어, Java로 프로젝트를 작성하기로 결정했다면 그것은 돌이킬 수없는 결정입니다. 데이터 파일에 자체 끓인 이진 형식을 사용하기로 결정한 경우, 이는 또한 돌이킬 수없는 결정입니다 (한 번 코드가 잘못 나오면 해당 형식을 계속 지원해야합니다). 그러나 GUI의 색상은 쉽게 조정할 수 있으며, 초기에 제외 된 기능은 나중에 추가 할 수 있으므로 이러한 문제에 대한 스트레스는 줄어 듭니다.

8
이것이 좋은 점입니다. 나는 "간단하게 유지"하는 데 어려움을 겪어야한다는 것을 인정해야한다. 그것은 다른 상황에서 다른 사람들에게 다른 것을 의미하는 것으로 보인다.
Kramii

3
나는 당신의 요점, 특히 "KIS"에 완벽하게 동의합니다. 그러나 나는 점점 더 많은 (더 젊은) 개발자들이 가장 단순한 컨텍스트조차 묘사하기 위해 오히려 복잡한 구조를 사용하는 경향을 봅니다.
chrmue

10
@chrmue : "Java로 팩토리 를 작성하는 방법" 참조 ;-)
Joonas Pulakka

8
음, 그리고 "8. 단순하게 유지하십시오".
Dawood ibn Kareem

7
# 6은 +10에 해당합니다.
Jim G.

55

단위 테스트 는 당신의 친구 입니다. 그것들을 구현하면 낮은 결합이 강제됩니다. 또한 프로그램의 "해킹 된"부분을 쉽게 식별하고 리팩토링 할 수 있음을 의미합니다. 또한 기존 기능을 중단하지 않도록 변경 사항을 신속하게 테스트 할 수 있습니다. 이를 통해 개발자는 문제를 해결하기 위해 코드를 복제하는 대신 기존 방법을 수정해야합니다.

단위 테스트는 코드에 대한 추가 문서로도 작동하여 각 부분의 기능을 간략하게 설명합니다. 광범위한 단위 테스트를 통해 프로그래머는 프로그램의 전체 아키텍처를 알 필요가 없어 기존 클래스 / 방법을 변경하고 사용할 수 있습니다.

좋은 부작용으로, 단위 테스트도 버그 수를 줄입니다.


3
매우 중요한 점입니다. 레거시 시스템, 많은 클래스, 많은 코드 줄, 문서, 단위 테스트가 없었습니다. 모든 코드 수정 및 개선 사항에 대한 단위 테스트를 부지런히 만든 후 시스템 설계는보다 깨끗하고 유지 관리가 가능한 상태로 발전했습니다. 그리고 우리는 중요한 핵심 부분 (단위 테스트에 포함됨)을 다시 쓸 용기가 있습니다.
Sam Goldberg

40

여기의 모든 사람들이 코드 rot 을 언급하는 것이 빠르며 , 나는 이것을 완전히 이해하고 동의하지만 여전히 더 큰 그림과 더 큰 문제를 놓치고 있습니다. 코드 썩음은 발생하지 않습니다. 또한 단위 테스트가 언급되어 있지만 실제로 문제를 해결하지는 않습니다. 좋은 단위 테스트 범위와 비교적 버그가없는 코드를 가질 수 있지만 여전히 코드와 디자인이 썩어 있습니다.

프로젝트에서 작업하는 개발자는 기능을 구현하는 데 어려움이 있으며 전체 아키텍처의 더 큰 그림을 그리워하지 않으므로 시스템에 대한 해킹을 구현합니다. 디자인을 시행하고 영향을 미치는 기술 리더십은 어디에 있습니까? 이 과정에서 코드 검토는 어디에 있습니까?

실제로 코드 부패로 고통받지는 않지만 팀 부패로 고통 받고 있습니다 . 사실 소프트웨어의 원래 제작자가 더 이상 팀에 속하지 않아도 문제가되지 않습니다. 기존 팀의 기술 책임자가 기본 설계를 완전히 이해하고 기술 책임자가되는 역할을 잘 수행한다면 문제가되지 않습니다.


아주 좋은 지적, 당신은 황소의 눈을 쳤다! 안타깝게도 여기서 일어나는 일입니다. 그리고 기술 책임자가없이 사물을 바꾸는 것은 불가능한 것 같습니다 ...
chrmue

4
@chrmue 내가 생각하는 방식대로, 그러나 나는 그것을 지치고 있습니다. 여러면에서 나는 내 주변의 모든 것이 얼마나 잘못되었는지 알지 못했을 때 다시 주니어 개발자가되기를 바랍니다. 내 중반 위기를 조기에 겪고있는 것 같습니다. 그러나 나는 돕고있다.
maple_shaft

1
@Murph 유지 관리 단계에서 모든 지식을 갖춘 팀장이없는 이유는 무엇입니까? 내가 상관했던 모든 보스는 팀 리더로부터 아무 것도 기대하지 않았으며, 팀 리더 일 때 나 자신도 기대하지 않았습니다.
maple_shaft

1
@maple_shaft a) 하나의 프로젝트에 전념 하는 팀장이 있다고 가정하지 않으며 첫 번째 요구 사항이 다소 적습니다 .b) 디자인 구현 (모두) 을 이해해야한다고 생각합니다. 단단한. 한편으로 우리 모두는 프로젝트에 대한 모든 지식의 단일 글꼴이 없어야한다고 주장하지만 여기서는 하나가 있어야한다고 말하고 있습니까? 추가되지 않습니까?
Murph

2
@maple_shaft 아마도 내가 심술 쟁이 된 프로그래머 일 것입니다 (-: 그러나 기존 코드베이스에서 깊이 따라야하는 구현 "스타일"이라는 문제가 있습니다.
Murph

18

우리가 할 수있는 몇 가지가 있습니다 :

한 사람에게 아키텍처에 대한 전반적인 책임을 부여하십시오. 그 사람을 선택할 때는 아키텍처를 개발하고 유지 관리 할 비전과 기술을 보유하고 다른 개발자가 아키텍처를 따르도록 도울 영향력과 권한을 갖도록하십시오. 그 사람은 경영진으로부터 신뢰 받고 동료들로부터 존경받는 노련한 개발자 여야합니다.

모든 개발자가 아키텍처를 소유하는 문화를 만듭니다. 모든 개발자는 아키텍처 무결성을 개발하고 유지 관리하는 프로세스에 참여해야합니다.

건축 결정을 쉽게 전달할 수있는 환경을 개발하십시오. 사람들에게 현재 프로젝트의 맥락뿐만 아니라 일반적으로도 디자인과 건축에 대해 이야기하도록 권장하십시오.

최상의 코딩 방법은 코드에서 아키텍처를보다 쉽게 ​​볼 수 있도록합니다. 리팩토링, 코드 주석, 단위 테스트 개발 등에 시간이 걸립니다. 명명 규칙 및 깨끗한 코딩 방법과 같은 것은 아키텍처를 전달하는 데 많은 도움이 될 수 있습니다. 시간을내어 자신의 표준을 개발하고 따르십시오.

필요한 모든 문서가 명확하고 간결하며 최신이며 액세스 가능한지 확인하십시오. 상위 및 하위 레벨 아키텍처 다이어그램을 모두 공개 (도움이 될 수 있음)하고 공개적으로 유지 보수 가능하게하십시오.

마지막으로 (자연 완벽 주의자로서) 건축 무결성은 가치있는 포부이지만, 함께 일하고 실제로 제품을 배송 할 수있는 팀을 구성하는 것과 같이 더 중요한 것들이있을 수 있음을 인식해야합니다.


1
+1, 특히 "함께 잘 작동하고 실제로는 제품을 배송 할 수있는 팀을 구축"하십시오.
deworde

1
한 사람이 건축을 담당하는 루트가되도록하는 것이 좋습니다. 그러나 그 책임이 자주 사용되는 경우 "팀 냄새"가 발생합니다. 팀은 한 사람이 답변을 제공하는 대신 자연스럽게 일반적인 결론을 내려야합니다. 왜? 프로젝트에 대한 전체 지식은 항상 공유되므로 한 사람에게 고정하면 결국 더 큰 문제가 발생할 수 있습니다. 그의 견해 만 충족되어 나머지 팀의 날개를 효과적으로 자릅니다. 대신 최고의 사람들을 고용하고 함께 일하게하십시오.
casper

1
@casper : 맞습니다. 당신은 내가 한 것보다 내가 생각했던 것을 더 잘 표현합니다.
Kramii

18

이 문제를 해결하는 방법은 루트에서 문제를 해결하는 것입니다.

내 설명은 Microsoft / .NET의 용어를 사용 하지만 모든 플랫폼 / 도구 상자에 적용됩니다.

  1. 이름 지정, 코딩, 체크인, 버그 흐름, 프로세스 흐름에 대한 표준을 사용하십시오.
  2. 표준을 준수하지 않는 팀원들에게 작별 인사를하는 것을 두려워하지 마십시오. 일부 개발자는 정의 된 표준 세트 내에서 작업 할 수 없으며 전장에서 코드 열을 깨끗하게 유지하기 위해 5 번째 열이됩니다.
  3. 숙련도가 낮은 팀원을 장기간 테스트에 할당하는 것을 두려워하지 마십시오.
  4. 썩은 코드 체크인을 피하기 위해 무기고의 모든 도구를 사용하십시오. 이에는 전용 도구와 빌드 파일, 프로젝트 파일, 디렉토리 구조 등을 테스트하는 미리 작성된 단위 테스트 가 포함됩니다.
  5. 약 5-8 명의 팀으로 구성된 팀에서 가장 좋은 사람이 거의 끊임없이 리팩토링을하도록하십시오. 다른 사람들이 남긴 혼란을 정리하십시오. 현장에서 최고의 전문가를 찾더라도 피할 수는 없지만 여전히 리팩토링에 의해 제약을받을 수 있습니다.
  6. 단위 테스트를 작성하고 유지 보수하십시오. 프로젝트를 깨끗하게 유지하기 위해 단위 테스트에 의존하지 마십시오.
  7. 모든 것을 토론하십시오. 팀에서 논의하기 위해 몇 시간을 소비하는 것을 두려워하지 마십시오. 이것은 정보를 전파하고 기술, 목표, 표준 등에 대한 혼동을 일으키는 잘못된 코드의 근본 원인 중 하나를 제거합니다.
  8. 컨설턴트가 코드를 작성하는 것에 매우 주의를 기울이 십시오 . 코드의 정의는 거의 말이 안될 것입니다.
  9. 체크인 전에 프로세스 단계로 검토하는 것이 좋습니다. 롤백 커밋을 두려워하지 마십시오.
  10. 릴리스 전 마지막 단계가 아니면 열기 / 닫기 원리를 사용하지 마십시오 . 썩는 코드가 냄새를 맡게됩니다.
  11. 문제가 발생할 때마다 솔루션을 구현하기 전에 문제를 최대한 이해하는 데 시간을 투자하십시오. 대부분의 코드 썩음은 솔루션 구현에서 완전히 이해되지 않은 문제까지 발생합니다.
  12. 올바른 기술을 사용하십시오. 이것들은 종종 세트로 제공되고 새로워 질 것입니다 : 지원되지 않는 매우 안정적이지만 쓸모없는 프레임 워크에 의존하는 것보다 미래에 지원 될 프레임 워크의 베타 버전에 의존하는 것이 좋습니다.
  13. 최고의 사람들을 고용하십시오.
  14. 커피 숍을 운영하지 않습니다.
  15. 관리가 최고의 건축가가 아니고 의사 결정 프로세스를 방해하는 경우 다른 직업을 찾으십시오.

1
이제 '예비 시간'에서 C #을 다시 작성하면서 100 가지 형식과 클래스를 가진 12 살짜리 VB6 앱을 유지하고 향상시켜야한다면 어떻게해야할까요?
jfrankcarr

7
# 3에 동의하지 않습니다. 시험은 훈련받지 않은 사람들에 대한 형벌로 여겨져서는 안됩니다. 실제로 모든 개발자가 수행해야하며 코딩 및 디자인만큼 중요하게 간주됩니다! Untrained 씨가 팀에 있다면 훈련을 위해 팀을 떠나십시오!.
NWS

1
"# 3에 동의하지 않습니다. 테스트는 훈련받지 않은 사람들에 대한 처벌로 간주되어서는 안됩니다." -내가 말한 것이 아니고 설명하지 말아야한다. 테스팅은 아직 당신이 모르는 사람들이 코드에 들어가기 위해 변화를 저지르는 것을 신뢰하게하는 좋은 방법이다. 내가 찾은 최고의 테스터는 코드를 제공하고 코드를 살펴보고 프로그램을 실행하여 자신의 역량을 증명하고 싶어하며 런타임에서 찾은 결과를 소스 코드와 연관시키는 능력을 보여줍니다. 그것은 처벌이 아닙니다-훈련.
casper

1
"# 10에 동의하지 않음-올바르게 수행하면 코드 품질에 도움이됩니다."이것은 내 업무 경험에서 절대적으로 잘못된 것입니다. 잠긴 코드는 리팩터링 할 수 없습니다. 즉, 잠금이 해제 될 때까지 현재 상태로 유지됩니다. 이 상태는 어떤 단계에서 작동하는 것으로 확인 될 수 있지만 나중 단계에서이 확인은 오탐 (false positive)입니다. 최종 시스템 테스트 전에 단계까지 리팩토링 할 수 있도록 모든 코드를 열어 두어야합니다.
casper

3
@casper : IMHO, 오픈 / 클로즈 원칙은 "소스를 변경할 수 없습니다"로 이해해서는 안되며 "코드가 얼어 붙는 것처럼 디자인"하는 것으로 이해해야합니다. 코드를 변경하지 않고도 코드를 필요에 따라 확장 할 수 있는지 확인하십시오. 그 결과 평균 코드보다 무관하게 결합되어 있고 응집력이 높습니다. 이 원칙은 타사에서 사용할 라이브러리를 개발할 때도 중요합니다. 코드를 입력하고 수정할 수 없기 때문에 확장 할 수 있어야합니다.
Kevin Cathcart

12

단위 테스트를 작성하는 동안 리팩토링하여 썩은 코드를 정리하십시오. 다음과 같은 경우, 사용자가 만지는 모든 코드에 대해 (이) 설계 부채를 지불하십시오.

  • 새로운 기능 개발
  • 문제 해결

다음을 통해 테스트 우선 개발주기를 크게 단축하십시오.

  • 코드 모듈을 스크립팅 언어로 변환하기위한 리팩토링
  • 빠른 클라우드 기반 테스트 머신 사용

내부적으로 응집력이 높은 유닛의 낮은 커플 링을 사용하기위한 리팩토링 코드 :

  • 더 단순하고 (더 많은) 기능 (루틴)
  • 모듈
  • 객체 (및 클래스 또는 프로토 타입)
  • 순수한 기능 (부작용없이)
  • 상속에 대한 위임 선호
  • 레이어 (API 포함)
  • 함께 작동 할 수있는 소규모의 다목적 프로그램 모음

유기적 성장이 좋다. 큰 선행 디자인이 나쁩니다.

현재 디자인에 대해 잘 알고있는 리더가 있어야합니다. 그렇지 않은 경우, 지식이있을 때까지 프로젝트 코드를 읽으십시오.

리팩토링 책을 읽으십시오.


1
+1 좋은 첫 번째 대답, 우리 자신을 소개하는 완벽한 방법!
yannis

11

간단한 답변 : 당신은 할 수 없습니다 .

당신이 작성하기위한 목표로해야하는 이유입니다 소형간단한 소프트웨어를. 쉽지 않습니다.

복잡하고 겉보기에 복잡한 문제를 가능한 한 간단하고 간결하게 정의하기에 충분히 오래 생각할 경우에만 가능합니다.

크고 복잡한 문제에 대한 솔루션은 작고 간단한 모듈을 기반으로하여 여전히 해결 될 수 있습니다.

즉, 다른 사람들이 지적했듯이 단순성과 느슨한 결합이 핵심 요소입니다.

이것이 가능하지 않거나 실현 가능하지 않은 경우, 아마도 연구 중일 것입니다 (알려진 간단한 해결책이나 알려진 해결책이없는 복잡한 문제). 연구가 유지 관리 가능한 제품을 직접 생산할 것으로 기대하지 마십시오.


9

1999 년부터 지속적으로 개발되어 온 제품의 코드 기반 작업을하고 있습니다. 코드베이스에서 가장 큰 해킹 소스는 ASP Classic 에서 ASP.NET으로 , ADO에서 ADO.NET으로, 포스트 백에서 Ajax로 , UI 라이브러리 전환, 코딩 표준 등 으로 포팅해야하는 여러 번부터 발생했습니다 .

우리는 코드베이스를 유지 관리 할 수있는 합리적인 작업을 수행했습니다. 우리가 그 일에 기여한 주요한 일은 :

1) 지속적인 리팩토링- 해킹되었거나 이해하기 어려운 코드를 건 드려야하는 경우 코드를 정리하는 데 시간이 더 걸리고이를 위해 일정에 여유가 있어야합니다. 단위 테스트는 회귀에 대해 더 쉽게 테스트 할 수 있기 때문에 이것을 훨씬 덜 무섭게 만듭니다.

2) 깔끔한 개발 환경 유지- 더 이상 사용되지 않는 코드를 삭제하고 프로젝트 디렉토리에 백업 사본 / 작업 사본 / 실험 코드가 남아 있지 않도록주의하십시오.

3) 프로젝트 수명 동안 일관된 코딩 표준-코드 표준에 대한 우리의 견해는 시간이 지남에 따라 진화합니다. 새로운 표준을 준수하기 위해 모든 코드를 수정하고 개조 할 시간이 없다면 프로젝트 수명 동안 시작한 코딩 표준을 고수하는 것이 좋습니다. 이제 헝가리어 표기법을 능가하는 것이 좋지만 새로운 프로젝트에 해당 교훈을 적용하고 새로운 프로젝트의 중간 단계로 전환하지 마십시오.


8

프로젝트 관리로 질문에 태그를 달았으므로 코드가 아닌 점을 추가하려고했습니다. :)

  • 회전율 계획-유지 보수 단계에 도달 할 때까지 전체 개발 팀이 사라 졌다고 가정합니다. 소금을 쓸만한 개발자는 자신의 시스템을 영원히 유지하기를 원치 않습니다. 시간이 남자 마자 핸드 오버 자료 준비를 시작하십시오.

  • 일관성 / 균일 성은 충분히 강조 될 수 없습니다. 이것은 '혼자서 가십시오'라는 문화를 방해하고 새로운 개발자가 의심이되는지 물어볼 것입니다.

  • 어떤 수준에서든 팀의 새로운 개발자가 빠르게 시작하고 실행할 가능성이 높기 때문에 사용 된 기술, 디자인 패턴 및 표준과 같은 주류를 유지하십시오.

  • 문서-특히 아키텍처-결정이 내려진 이유 및 코딩 표준. 또한 비즈니스 도메인을 문서화 할 때 참조 /주의 사항 / 로드맵을 유지하십시오. 도메인 비즈니스 경험이없는 개발자에게 기업 비즈니스가 자신의 업무를 설명하는 것이 얼마나 어려운지 놀랄 것입니다.

  • 현재 개발 팀을위한 것이 아니라 미래의 유지 보수 개발자를 생각하십시오. 이것이 모든 페이지에 관련 디자인 및 코딩 표준 문서에 대한 하이퍼 링크를 놓는 것을 의미한다면, 그렇게하십시오.

  • 아키텍처와 특히 코드 레이어가 명확하게 구분되고 분리되어 있는지 확인하십시오. 새로운 기술이 등장함에 따라 코드 레이어를 교체 할 수 있습니다. 예를 들어 Web Forms UI를 HTML5 jQuery UI 등으로 대체 할 수 있습니다. 수명 연장을 위해 1 년 정도를 구매하십시오.


7

고도로 유지 가능한 코드의 한 가지 특성은 함수 순도 입니다.

순도는 함수가 동일한 인수에 대해 동일한 결과를 반환해야 함을 의미합니다. 즉, 다른 기능의 부작용에 의존해서는 안됩니다. 또한 부작용이없는 경우 유용합니다.

이 특성은 결합 / 응집 특성보다 쉽게 ​​관찰 할 수 있습니다. 당신은 그것을 달성하기 위해 당신의 길을 벗어날 필요가 없으며, 나는 개인적으로 그것을 더 가치 있다고 생각합니다.

함수가 순수하면 그 유형 자체가 매우 훌륭한 문서입니다. 또한 인수 / 반환 값의 관점에서 문서를 읽고 읽는 것이 전역 상태 (다른 스레드 O_O에 의해 액세스 될 수 있음)를 언급하는 것보다 훨씬 쉽습니다.

유지 보수를 돕기 위해 순도를 광범위하게 사용하는 예로서 GHC 를 볼 수 있습니다 . 대규모 리팩토링이 수행되고 새로운 주요 기능이 여전히 도입되고있는 약 20 년 전의 대규모 프로젝트입니다.

마지막으로, "간단하게 유지"요점을 너무 좋아하지 않습니다. 복잡한 것을 모델링 할 때 프로그램을 단순하게 유지할 수 없습니다. 간단한 컴파일러를 만들면 생성 된 코드가 느리게 작동 할 수 있습니다. 물론 개별 기능을 간단하게 만들 수는 있지만 그 결과 전체 프로그램이 단순하지는 않습니다.


2
당신이 묘사하는 또 다른 이름은 결정론적인 속성입니다
jinglesthula

6

다른 답변 외에도 레이어를 권장합니다. 너무 많지는 않지만 다른 유형의 코드를 분리하기에 충분합니다.

대부분의 응용 프로그램에 내부 API 모델을 사용합니다. 데이터베이스에 연결하는 내부 API가 있습니다. 그런 다음 UI 레이어. 다른 사람들이 응용 프로그램의 다른 부분을 방해하거나 중단하지 않고 각 수준에서 작업 할 수 있습니다.

또 다른 접근 방식은 모든 사람이 comp.risksDaily WTF를 읽 도록하여 잘못된 디자인과 잘못된 프로그래밍의 결과를 배우고 Daily WTF 에 게시 된 자체 코드를 보는 것을 두려워 합니다.


6

이러한 답변 중 많은 부분이 처음부터 큰 팀에 초점을 맞추는 것처럼 보이기 때문에 스타트 업을 위해 2 인 개발 팀 (디자이너를 포함하는 경우 3 명)의 일부로 내 견해를 밝힐 것입니다.

당연히 단순한 디자인과 솔루션이 가장 좋지만, 목에 숨을 쉬면서 급여를 지불하는 사람이있을 때 반드시 가장 우아하고 단순하며 유지 관리 가능한 솔루션에 대해 생각할 시간이 없습니다. 그것을 염두에두고, 나의 첫 번째 큰 포인트는 다음과 같습니다.

설명서 주석이 아니라 코드는 대부분 자체 문서화되어야하지만 디자인 문서, 클래스 계층 및 종속성, 아키텍처 패러다임 등과 같은 것입니다. 새로운 프로그래머 나 기존 프로그래머가 코드베이스를 이해하는 데 도움이되는 모든 것. 또한 "이 기능의 요소에이 클래스를 추가"와 같이 팝업되는 이상한 의사 라이브러리를 문서화하면 사람들이 기능을 다시 쓰지 못하게되므로 도움이 될 수 있습니다.

그러나 시간 제한이 심한 경우에도 명심해야 할 또 다른 장점은 다음과 같습니다.

해킹 과 빠른 수정을 피하십시오 . 빠른 수정이 실제 수정이 아닌 한 항상 근본적인 문제를 파악한 다음 수정하는 것이 좋습니다. 문자 그대로 "다음 2 분 안에이 작업을 수행하거나 해고"시나리오가 없다면 나중에 코드를 수정하지 않기 때문에 지금 수정을 수행하는 것이 좋습니다. 다음 작업으로 넘어갑니다.

그리고 내가 개인적으로 좋아하는 팁은 인용문에 더 가깝지만 소스는 기억할 수 없습니다.

"당신을 따르는 사람이 당신이 사는 곳을 알고있는 살생 정신병자 인 것처럼 코딩하십시오"


구문 강조를 사용하여 함수 및 클래스 위치에서 코드 세그먼트를 분리하는 경우에도 함수 및 클래스 주석이 항상 유용하다는 것을 알았습니다. 함수 코드에 주석을 거의 넣지 않지만 /** Gets the available times of a clinic practitioner on a specific date. **/or 와 같은 모든 클래스와 함수에 대한 줄을 작성합니다 /** Represents a clinic practitioner. **/.
Nick Bedford

5

언급되지 않았지만 중요하다고 생각하는 한 가지 원칙은 개방 / 폐쇄 원칙 입니다.

개발 및 테스트 된 코드를 수정해서는 안됩니다. 이러한 코드는 모두 봉인되어 있습니다. 대신 하위 클래스를 사용하여 기존 클래스를 확장하거나 래퍼, 데코레이터 클래스를 작성 하거나 적합한 패턴을 사용하십시오. 그러나 작업 코드를 변경하지 마십시오 .

그냥 내 2 센트.


작업 코드로 표현 된 비즈니스 요구 사항이 변경되면 어떻게됩니까? 잘못 고려되었지만 기술적으로 '작동하는'코드에 손대지 않으면 장기적으로, 특히 필요한 변경을 수행 할 때가 다가올 수 있습니다.
jinglesthula

@jinglesthula : 확장을 위해 개방한다는 것은 새로운 기능을 기존 인터페이스의 새로운 구현 (예 : 클래스)으로 추가 할 수 있음을 의미합니다. 물론, 잘못 구조화 된 코드는이를 허용하지 않습니다. 기존 코드를 수정하는 대신 새 코드를 추가하여 코드를 "변경"할 수있는 인터페이스와 같은 추상화가 있어야합니다.
Giorgio

5
  • 스카우트가 되십시오 . 찾은 것보다 항상 코드를 깨끗하게 유지하십시오.

  • 깨진 창을 수정하십시오 . 버전 3.0에있을 때 이러한 모든 의견은 "버전 2.0 변경"입니다.

  • 주요 해킹이있는 경우 팀으로 더 나은 솔루션을 설계하고 수행하십시오. 팀으로 해킹을 해결할 수 없다면 시스템을 충분히 이해하지 못합니다. "도움을 구하려면 성인에게 물어보십시오." 가장 오래된 사람들은 전에 이것을 보았을 것입니다. 시스템 다이어그램을 그리거나 추출하십시오. 특히 상호 작용 다이어그램으로 해킹 된 사용 사례를 그리거나 추출해보십시오. 이것은 수정되지 않지만 최소한 볼 수 있습니다.

  • 더 이상 특정 방향으로 설계를 추진 한 가정은 무엇입니까? 그 혼란의 일부 뒤에 숨어있는 작은 리팩토링이있을 수 있습니다.

  • 시스템의 작동 방식을 설명하고 (하나의 유스 케이스조차도) 서브 시스템에 대해 반복해서 사과해야하는 경우 문제가됩니다. 어떤 행동이 시스템의 나머지 부분을 더 단순하게 만드는가? 재 작성할 클래식 서브 시스템은 운영 시맨틱 및 구현으로 다른 모든 서브 시스템을 오염시키는 서브 시스템입니다. "아, 값을 froo 하위 시스템으로 보내기 전에 값을 groz로 설정 한 다음, froo에서 출력을 얻을 때 다시 값을 해제해야합니다. 사용자 및 스토리지에서 읽을 때 모든 값을 groz'ed해야 할 수도 있습니다. 두 개 이상의 다른 grozification이있을 때 더욱 흥미로워집니다.

  • 팀이 일주일 동안 경고를 없애 실제 문제가 보이도록합니다.

  • 모든 코드를 코딩 표준으로 다시 포맷하십시오.

  • 버전 관리 시스템 이 버그 추적기에 연결되어 있는지 확인하십시오 . 이것은 미래의 변화가 훌륭하고 책임감이 있으며, 왜 그런지를 해결할 수 있음을 의미합니다.

  • 고고학을 수행하십시오. 원본 디자인 문서를 찾아 검토하십시오. 사무실 구석, 버려진 사무실 공간 또는 서류 보관함에있는 오래된 PC에 아무도 열지 않을 수 있습니다.

  • 위키에서 디자인 문서를 다시 공개하십시오. 이것은 지식을 제도화하는 데 도움이됩니다.

  • 릴리스 및 빌드에 대한 체크리스트와 유사한 절차를 작성하십시오. 이것은 사람들이 생각할 필요가 없도록하여 문제 해결에 집중할 수 있습니다. 가능하면 빌드를 자동화하십시오.

  • 지속적인 통합을 시도하십시오 . 빌드에 실패할수록 프로젝트가 레일에서 소비하는 시간이 줄어 듭니다.

  • 팀장이 이런 일을하지 않으면 회사에 좋지 않습니다.

  • 모든 새로운 코드가 측정 된 커버리지로 적절한 단위 테스트를 받도록하십시오. 따라서 문제는 훨씬 나빠질 수 없습니다.

  • 단위 테스트되지 않은 오래된 비트 중 일부를 단위 테스트하십시오. 이를 통해 변화에 대한 두려움을 줄일 수 있습니다.

  • 가능하면 통합 및 회귀 테스트를 자동화하십시오. 최소한 점검표가 있습니다. 조종사는 영리하고 많은 돈을 받고 점검표를 사용합니다. 그들은 또한 거의 드물게 조입니다.


4

Steve McConnell이 작성한 Code Complete 를 읽고 다시 읽습니다 . 초기 프로젝트 설계에서 단일 코드 라인 및 그 사이의 모든 것에 이르기까지 훌륭한 소프트웨어 작성의 성경과 같습니다. 내가 가장 좋아하는 것은 수십 년의 견고한 데이터로 백업된다는 것입니다. 다음으로 최고의 코딩 스타일이 아닙니다.


3

이것을 "윈체스터 미스터리 하우스 효과"라고 ​​부릅니다. 집처럼, 그것은 간단하게 시작했지만, 수년 동안 많은 다른 노동자들이 더 이상 그것을 전혀 이해하지 못하는 전반적인 계획없이 많은 이상한 기능을 추가했습니다. 이 계단은 왜 아무데도 가지 않고 왜 그 문은 한 방향으로 만 열립니까? 누가 알아?

이 효과를 제한하는 방법은 확장을 처리 할 수있을만큼 융통성이있는 우수한 디자인으로 시작하는 것입니다. 이에 대한 몇 가지 제안이 이미 제공되었습니다.

그러나 손상이 이미 완료된 작업을 수행하는 경우가 많으며, 비싸고 잠재적으로 위험한 재 설계 및 재 작성을 수행하지 않으면 좋은 설계를하기에는 너무 늦습니다. 그러한 상황에서는 혼돈을 어느 정도 수용하면서 혼란을 제한하는 방법을 찾는 것이 가장 좋습니다. 모든 것이 거대하고 추악한 싱글 톤 '관리자'클래스를 거치거나 데이터 액세스 계층이 UI에 밀접하게 결합되어 있지만이를 다루는 법을 배우는 것이 디자인 감도에 문제가 될 수 있습니다. 해당 프레임 워크 내에서 방어 적으로 코드를 작성하고 과거의 프로그래머의 '고스트'가 나타날 때 예기치 않은 결과를 기대하십시오.


2

코드 리팩토링단위 테스트 는 완벽합니다. 그러나이 장기 실행 프로젝트가 해킹을 당하기 때문에 경영진이 부패를 청소하려고하지 않습니다. 누군가가 사람들을 훈련시키고 문제 / 요청을 분석하기에 충분한 자원을 할당하지 않기 때문에 팀은 해킹을 도입해야합니다.

장기 실행 프로젝트를 유지 관리하는 것은 개별 개발자만큼 프로젝트 관리자의 책임입니다.

사람들은 그것을 좋아하기 때문에 핵을 도입하지 않습니다. 그들은 상황에 의해 강요됩니다.


상황에 의해 강제? 사람들은 (a) 더 잘 알지 못합니다 => 코칭이 필요합니다. (b) 더 큰 그림을 보지 못합니다. => 의사 소통, 문서 및 징계가 필요합니다. (c) 그들이 더 똑똑하다고 생각 합니다. 극복해야 할 장애물 (d) 상황에 따라 강요 => 시간이 지나면 빠른 핫픽스 를 사용해 도 괜찮지 만, 나중에 책임을 맡고 코드를 정리해야합니다. 다른 "환경"은 단순히 BS 입니다. 그 경험 규칙에는 예외가 있지만 가장 이른 예외는 "게으른"입니다.
JensG

2

나는 비 기술적 문제와 (아마도) 실용적인 접근 방식을 원합니다.

관리자가 기술 품질 (관리 가능한 코드, 간단한 아키텍처, 안정적인 인프라 등)에 신경 쓰지 않으면 프로젝트를 개선하기가 어려워집니다. 이 경우, 해당 관리자를 교육하고 유지 보수기술적 부채 처리에 노력을 "투자"해야 합니다.

이 책에서 찾은 코드 품질로 꿈을 꾸는 경우 이에 대해 우려하는 보스가 필요합니다.

또는 "프랑켄슈타인 프로젝트"를 길들이고 싶다면 이것들이 제 팁입니다 :

  • 구성 및 단순화
  • 기능 단축
  • 효율성보다 가독성을 우선시하십시오 (물론 수용 가능하고 일부 효율성 향상이 너무 비참하여 유지할 수없는 경우)

내 경험에 따르면 프로그래밍은 (최소한 인기있는 구조적 패러다임에서) 등장하는 것이 아니라 엔트로피입니다. 사람들이 "그냥 작동"하는 코드를 작성할 때 조직을 잃는 경향이 있습니다. 이제 코드를 구성하려면 시간이 필요하며 때로는 작동시키는 것보다 훨씬 많은 시간이 필요합니다.

기능 구현 및 버그 수정 외에도 코드 정리에 시간이 걸립니다.


"... 프로젝트가 끝났습니다" – 내 경험상, 반드시 그런 것은 아닙니다. 대안은 해당 관리자를 교육하고 유지 보수성기술적
논쟁

죄송합니다. 관리자가 기술 부채에 대한 모든 조언을 무시했을 때 이미 경험이 있었기 때문에 글을 쓸 수 없었습니다. 그러나 나는 당신이 옳다고 생각합니다. 프로젝트를 포기한 지 약 1 년이 지나면 관리자는 기술 팀에 대한 모든 권한을 잃어 버렸습니다.
Eric. 무효

1

수많은 답변 중 어느 것도 명백한 것을 강조하지 않았다는 사실에 놀랐습니다. 소프트웨어를 수많은 독립적 인 작은 라이브러리로 구성하십시오. 작은 라이브러리가 많으면 크고 복잡한 소프트웨어를 구성 할 수 있습니다. 요구 사항이 변경되면 전체 코드베이스를 버리지 말고 큰 호닝 코드베이스를 수정하여 현재 수행중인 작업 이외의 작업을 수행하는 방법을 조사 할 필요가 없습니다. 요구 사항이 변경된 후에도 여전히 해당 라이브러리 중 어떤 라이브러리와 새로운 기능을 갖기 위해 이들을 결합하는 방법 만 결정하면됩니다.

라이브러리를 쉽게 사용할 수 있도록 해당 라이브러리의 프로그래밍 기술을 사용하십시오. 함수 포인터를 지원하는 객체 지향이 아닌 언어는 실제로 객체 지향 프로그래밍 (OOP)을 지원합니다. 예를 들어 C에서는 OOP를 수행 할 수 있습니다.

많은 프로젝트간에 작은 독립적 인 라이브러리를 공유하는 것을 고려할 수도 있습니다 (git 서브 모듈은 당신의 친구입니다).

말할 필요도없이, 각각의 작은 독립적 인 라이브러리는 단위 테스트를 거쳐야합니다. 특정 라이브러리를 단위로 테스트 할 수없는 경우 무언가 잘못한 것입니다.

C 또는 C ++를 사용하고 작은 .so 파일이 많다는 생각이 마음에 들지 않으면 모든 라이브러리를 더 큰 .so 파일로 연결하거나 정적 연결을 수행 할 수 있습니다. Java의 경우에도 마찬가지입니다. .so를 .jar로 변경하십시오.


이것은 내 관점에서 너무 이론적 인 것 같습니다. 물론 필자의 질문에서 언급 한 프로젝트는 여러 라이브러리와 모듈로 구성되었습니다. 소프트웨어 개발의 지난 26 년 동안의 경험은 프로젝트가 나이가 들수록 초기 조직이
된다는 것

0

간단 함 : 유지 보수 가능한 개수의 움직이는 부품이있을 때까지 대부분의 코드 유지 보수 비용을 0으로 줄입니다. 변경할 필요가없는 코드는 유지 보수 비용이 들지 않습니다. 나는 진정으로이 코드를 만들기위한 목표로하는 것이 좋습니다 제로 없는 많은 작은과 까다로운 리팩토링의 반복을 통해 비용을 절감하기 위해 노력하고, 유지 보수 비용을. 즉시 비용을 제로로 만드십시오 .

물론, 그것은 소리보다 훨씬 더 어렵습니다. 그러나 시작하기는 어렵지 않습니다. 코드베이스의 덩어리를 가져 와서 테스트하고 인터페이스 디자인이 엉망인 경우 그 위에 멋진 인터페이스를 구성하고 동시에 변경 이유가없는 것처럼 안정적이고 안정적인 코드베이스 부분을 성장시킬 수 있습니다. 신뢰할 수없고 불안정한 부품을 축소합니다. 유지하기 위해 악몽처럼 느껴지는 코드베이스는 모든 것이 신뢰할 수없고 변경되기 쉬운 것으로 간주되기 때문에 변경 해야하는 움직이는 부분을 그렇지 않은 부분과 구별하지 않는 경우가 많습니다.

실제로 코드베이스의 구성을 "안정한"부분과 "불안정한"부분으로 분리하는 모든 방법을 사용하는 것이 좋습니다. 안정적인 부분은 재구성하고 변경할 수있는 거대한 PITA입니다. "안정된"섹션에 속하는 경우 변경 및 재 구축)

유지 관리를 어렵게 만드는 것은 코드베이스의 크기가 아닙니다. 유지해야하는 코드베이스의 크기입니다. 예를 들어 운영 체제 API를 사용할 때마다 수백만 줄의 코드에 의존합니다. 그러나 운영 체제의 소스 코드를 유지할 필요가 없기 때문에 제품의 유지 관리 비용에 영향을 미치지 않습니다. 난 그냥 코드를 사용하고 작동합니다. 내가 사용하고 유지 관리 할 필요가없는 코드는 결국 유지 관리 비용이 들지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.