코드 일관성과 코드 개선 사이의 올바른 균형은 무엇입니까?


53

최근에는 코드 스타일에 관해 동료와 토론했습니다. 그는 API 사용과 일반적인 패턴이 코드 모양이 아닌 것처럼 코드 전체가 아니라면 주변 코드와 가능한 한 비슷해야한다고 주장했습니다 (중괄호 위치 지정, 대문자 사용 등) . 예를 들어 C #에서 DAO 클래스에 메서드를 추가하는 경우 해당 클래스의 다른 메서드 중 어느 것도 사용하지 않더라도 코드를 깨끗하고 유지 관리하기 쉽도록 LINQ를 사용하려고합니다. 그러나 내 동료는 해당 클래스의 기존 스타일에 위배되어 이해하기 어려울 수 있으므로 해당 인스턴스에서 사용해서는 안된다고 주장합니다.

처음에 나는 그의 입장이 다소 극단적 인 것을 알았지 만, 잠시 동안 생각한 후에 그의 요점을보기 시작했다. 가상의 LINQ 예제를 사용하면 동료가 LINQ에 익숙하지 않기 때문에이 클래스에 포함되어 있지 않을 수 있습니다. 그렇다면 코드를 사용하지 않으면 동료 개발자가 코드를 유지 관리하기가 쉽지 않습니까? 반면에, 그러한 기술을 사용하면 코드가 더 깨끗해질 것이라고 생각한다면 주변 코드와 크게 다르더라도 사용해서는 안됩니까?

동료의 주장의 요점은 우리가 서로 다른 방식으로 코드베이스에서 유사한 기능을 구현하려고 할 때 각자의 방식이 "최고"라고 생각하면 결국 코드 전체가 더 어려워진다는 것입니다. 이해하다. 그러나 현재로서는 기존 코드를 너무 맹목적으로 따르면 품질이 시간이 지남에 따라 천천히 썩을 것이라고 생각합니다.

그렇다면 패턴은 코드 스타일의 일부로 어느 정도까지 유지되며 일관성 유지와 개선 사이의 경계를 어디에서 그려야합니까?


14
그렇다면 모두가 "나쁜"방식으로 제한한다면 코드 품질은 어떻게 향상 될까요?
이즈 카타


LINQ를 작성할 때 LINQ to SQL을 의미하지 않습니까? 그렇다면 친구와 동의 할 수 있습니다. 당신이 LINQ에 대해 이야기하고 있다면 나는 그에게 동의하지 않습니다. 요즘에는 누구나 LINQ에 익숙해야합니다. 그들의 선택이 아닙니다. 그들은 친숙하게 지불됩니다.
Piotr Perak

@Peri 나는 기본적인 LINQ를 의미했다. 나의 예제는 IEnumerableDAO가 아닌 s로 작업하는 것에 관한 것 같아요 .
Robert Johnson

2
ICYMI-이 주제에 대한 딜버트 만화 : dilbert.com/strips/2013-09-21
Jim Bethancourt

답변:


53

보다 일반적인 답변을 제공하려면 :

이와 같은 경우 서로 반대되는 두 가지 프로그래밍 "모범 사례"가 있습니다. 코드 일관성이 중요하지만 작업을 수행 할 수있는 최상의 방법을 선택하는 것입니다. 이 딜레마에 대한 정답은 없습니다. 몇 가지 요인에 따라 다릅니다.

  • "올바른"방법은 얼마나 유익합니까?

    • 때로는 새롭고 개선 된 모범 사례가 성능을 크게 향상시키고 버그를 제거하며 프로그래밍하기가 훨씬 쉬워지는 등의 경우가 있습니다. 이러한 경우 새 방법을 사용하는 데 크게 의지 할 것입니다. 다른 한편으로 , "올바른 방법"은 구문 설탕, 또는 실제로 우월하지 않은 것을하는 합의 된 관용적 방법에 지나지 않습니다. 이 경우 코드 일관성이 더 중요 할 것입니다.
  • 불일치가 얼마나 큰 문제입니까?

    • 새 코드와 레거시 코드는 어떻게 상호 연결되어 있습니까? 새 코드가 라이브러리의 일부입니까? 프로그램의 많은 부분으로 전달되는 객체를 생성합니까? 이러한 경우 일관성이 매우 중요합니다. 새로운 API를 사용하거나 일반적인 방식으로 새로운 방식을 사용하면 프로그램의 다른 곳에서 가정을 어기는 미묘하게 다른 결과가 생성 될 수 있습니다. 반면에 상당히 고립 된 코드를 작성하는 경우 불일치는 문제가되지 않습니다.
    • 코드베이스는 얼마나 크고 얼마나 성숙합니까? 얼마나 많은 개발자가 이해하고 작업해야합니까? 대규모 프로젝트에는 합의 된 일관된 표준이 훨씬 더 중요합니다.
    • 최신 기능을 지원하지 않는 이전 환경에서 코드를 실행해야합니까?

이러한 문제의 균형에 따라 어느 경로를 선택해야하는지 선택해야합니다. 나는 개인적으로 일관성을 유지하기 위해 일관성이 거의 가치가 없으며, 상당한 비용이 들지 않는 한 최신의 가장 좋은 방법을 선호합니다.

그것이 최선의 방법을 사용하도록 기존 코드를 재 작성 : 물론, 세 번째 옵션이 일치가. 이것이 필요할 때가 있지만 비용이 많이 듭니다.


7
매우 좋고 균형 잡힌 답변 (+1). 내 경험상 각 팀 구성원이 다른 팀 구성원이 이해하기 어려울 수있는 새롭고 다른 관용구를 자유롭게 사용할 수있는 것보다 모든 사람이 비교적 이해하기 어려운 관용구에 동의하면 팀의 생산성이 높아질 수 있습니다. "최신 사례를 사용하고 일관성을 유지하기 위해 기존 코드를 다시 작성"이라는 문에 관한 한 가지 작은 점은 "최신"이 자동으로 "더 나은"것을 의미하지는 않습니다. 항상 상황을 결정해야합니다.
Giorgio

1
@Giorgio, 피드백 주셔서 감사합니다; 나는 마지막 요점의 언어를 조정했다.

6
Giorgio의 좋은 답변과 좋은 의견. 팀 / 문화에 따라이 예에서 혼자 시작하는 대신 조정 된 팀 채택이 가능하다는 점을 고려해 볼 가치가 있습니다. 이렇게하면 유지 관리와 관련된 일부 위험이 줄어 듭니다 (모든 사람이 탑승 할 때). (즉, 과거에 작성한 코드가 아니라 현재 팀의 실제 기술에 더 중점을 둡니다.)
Matt

+1. 철저하고 균형 잡힌 답변-다양한 시나리오에 대한 적절한 고려. 다시 Giorgio의 좋은 의견.
Robert Johnson

1
새로운 관용구, 기술의 채택과 관련하여 : 나는 새로운 프로젝트의 시작을 새로운 것을 소개하기에 좋은 시점으로 생각합니다. 그 후, 전체 프로젝트 기간 동안 코드 스타일을 가능한 일관성있게 유지해야합니다. 나는 최근에 5 살짜리 코드를 파헤쳐 야했고 팀 전체가 우리가 합의한 일반적인 아키텍처와 관용구를 고수했기 때문에 코드를 통해 길을 찾을 수있어서 매우 기뻤습니다! ) 프로젝트 시작시.
Giorgio

26

일관성 유지는 내 관점에서 거의 가치가 없습니다. 지속적으로 개선해야합니다.

동료의 입장은 혁신을 방해합니다. 일관성 인수는 LINQ 를 사용하기 위해 모든 코드를 마이그레이션 하는 경우에만 LINQ와 같은 상황을 사용할 수있게합니다 . 글쎄요, 우린 시간이 없어요?

차라리 일부 코드가 여전히 foreachArrayLists를 수행하고 있고 다른 부분 IEnumerable<T>은 시간이 끝날 때까지 가장 오래된 방식을 고수하는 대신 LINQ on을 사용 하는 일관성이 없습니다 .

관련성을 유지하고 새로운 일을하는 방법을 배우는 것은 동료의 책임입니다.


3
"관련성을 유지하고 새로운 일을하는 방법을 배우는 것은 동료의 책임입니다."
Giorgio

8

API 일관성은 공개 및 내부 API 모두에 매우 중요합니다.

코드 형식 일관성이 중요하며 모든 사람에 대해 동일한 형식 규칙을 사용하는 자동 형식 도구를 사용하는 것이 이상적입니다. 공유 버전 제어 코드베이스로보다 쉽게 ​​생활 할 수 있습니다.

지역 변수와 같은 것들에 대해서도 명명 규칙이 일관되어야합니다.

정적 분석 도구를 사용하여 특정 다른 규칙 및 모범 사례를 시행해야합니다 (그러나 이러한 도구의 기본값을 맹목적으로 따르지 말고 기본값은 때로는 미쳤을 수 있습니다). 당신이 그것을 정당화 할 수 있다면 일시적으로 확인하십시오 (일반적으로 주석 안에 지시문으로).

위에 나열된 것과는 별도로 함수 / 메소드 내부에서 발생 하는 작업은 자체적으로 좋은 코드 인 한 어떤 식 으로든 일관성을 유지할 필요가 없습니다 . 좋은, 이해, 주석 코드는 매우 중요하지만, 컴파일러와 정적 분석 도구가 일치하는 코드를 생각하면 그 이후, 그것으로 충분 일치합니다.


LINQ와 같은 새로운 언어 기능 (정확히 새로운 것은 아님)에 대해 고려해야 할 유일한 것은 코드가 사용될 모든 곳 에서 새로운 버전의 언어 / 라이브러리 가 사용됩니까? 확실하지 않은 경우 호환되는 것으로 알려진 기능을 사용하십시오. 물론 시스템 전체에서 버전 업그레이드를 추진하는 것을 막을 수는 없으므로 새로운 멋진 기능을 사용할 수 있습니다.

또한 코드를 사용하는 모든 개발자는 최신 상태를 유지해야하므로 모든 .NET 개발자는 LINQ를 알고 있어야하며, 배우지 않으면 강의를 위해 강의를해야합니다. 어떤 이유로 든이 사업에 종사).


6

이에 대한 대답은 간단합니다.

일관성이 가장 중요합니다.

그러나 경고가 있습니다 ...

당신과 당신의 동료는 잘못된 종류의 일관성에 집착하고있을 것입니다

구현은 일회용입니다. 테스트 스위트의 품질과 종합성에 따라 다양한 정도의 편의로 완전히 점검 할 수 있습니다. "이것은 속성이어야합니까?", "얇은 코드는 하위 레벨 구조 대신 LINQ를 사용하지 않습니까?" 모호한 가치가 있습니다. 구현 수준에서 모든 측정 값을 일관성 값에 연결하기가 어렵습니다. 이 수준에서 물어 보는 것이 더 좋은 질문은 "이 코드가 광고 된대로 작동합니까?"입니다. TL; DR 구현 일관성은 "작은 마음"이 홉 고블린을 얻는 곳입니다.

여기서 일관성이 중요하지 않은 이유는 무엇입니까? 구현에는 일반적으로 적은 수의 기고자가 있습니다. 대부분의 방법은 작성되고 다시는 손대지 않습니다. 나머지 코드 중에서 거의 두 가지 기여자가있는 메소드 수입니다. 이 패턴은 광고 무한대로 계속 됩니다. 이러한 맥락에서 일관성은 그다지 중요하지 않습니다. 코드의 저장 수명이 꽤 작은 경우 ( 몇 년 ) 공격적인 일관성으로 인한 이익은 중요하지 않습니다.

이것은 당신이 당신의 구현에 열중해야한다고 말하는 것이 아닙니다. 오히려 멋지고 깨끗하며 단순한 디자인은 어리석은 보일러 판 일관성 방법보다 방법으로 미래의 미래 유지 보수 자에게 훨씬 가치 있다고 말할 것입니다. 이것은 우리를 진짜 요점으로 데려갑니다 ...

API는 일회용이 아닙니다.

이것은 모든 API 코드 수준, 웹 서비스, SDK 등입니다. 일관성이 있어야합니다. 이러한 다양한 일관성으로 인한 생산성 이점은 여러 가지 이유로 막대합니다.

통합 테스트 :

API의 일관성을 유지하면 일련의 통합 테스트를 작성할 수 있습니다. 이를 통해 개발자는 구현 세부 사항을 자유롭게 교환하고 즉시 검증 할 수 있습니다. 공동 작업 쓰레기를 LINQ로 바꾸고 싶습니까? 통합 테스트가 실행됩니까? 또한 생산 준비를 할 때의 검증도 제공합니다. 컴퓨터가 빠르기 때문에 하나의 랩탑이 일상적인 작업을 수행하는 수천 명의 테스터의 작업을 수행 할 수 있습니다. 조직의 직원 수를 크게 늘리는 데 큰 도움이됩니다.

생산력

API가 일관된 경우 API의 다른 부분을 사용하여 배운 내용을 따르면 API 사용 방법에 대해 추측 할 수 있습니다. API가 자연스럽고 일관된 "모양과 느낌"을 제공하기 때문입니다. 이는 고객이 문서를 선별하는 데 더 적은 시간을 소비한다는 것을 의미합니다. 온 보딩이 더 쉽고 저렴합니다. API를 개발 한 사람들에게 적은 질문이 있습니다. 일관성은 모든 사람을 승자로 만듭니다

이 시나리오에서 일관성이 중요한 이유는 무엇입니까? API는 구현과 정확히 반대되는 문제가 있기 때문입니다. 그것들을 사용하는 사람들의 수는 일반적으로 그들의 구현에 기여하는 사람들의 수보다 훨씬 많습니다. 약간의 일관성에서 작은 이익이 배가되고 일관성을 유지하는 비용이 상각됩니다.

결론

일관성은 비싸다. 얼굴은 생산성을 떨어 뜨립니다. 개발자를 제한하고 삶을 어렵게 만듭니다. 문제를 해결할 수있는 방법에 제한이있어 때로는 최적화되지 않은 방식으로 문제를 해결해야합니다. 이것은 종종 그들이 이해하지 못하거나 이해가 잘 안되거나 특권이없는 이유 (계약, 더 큰 조직 또는 조직 간 정책)입니다.

Raymond Hettinger는 Pycon 2015에서 파이썬 프로그래머 팀을위한 PEP8 스타일 가이드를 사용하는 것에 대해 몇 가지 훌륭한 지적을했습니다. 그는 코드 조각에 대한 스타일 일관성에 대한 집착으로 인해 코드 검토자가 심각한 논리와 디자인 결함을 놓칠 수 있음을 보여주었습니다. 그의 가설은 문체 적 불일치찾는 것이 쉽다고 요약 될 수있다 . 코드의 실제 품질을 결정하는 것은 어렵다

여기서 요점은 중요합니다. 일관성이 중요한 부분을 식별하고 적극적으로 보호하십시오. 중요하지 않은 곳에서 시간을 낭비하지 마십시오. 일관성 값을 측정하기위한 객관적인 방법을 제공 할 수없는 경우 (위의 경우 "유효 인력 수", 생산성의 함수로서 비용) 수익이 상당하다는 것을 입증 할 수없는 경우 당신의 조직.


4

LINQ에 익숙하지 않습니까? 그렇다면 코드를 사용하지 않으면 동료 개발자가 코드를 유지 관리하기가 쉽지 않습니까?

C # 언어는 여전히 발전하고 있습니다. 사람들이 C # 1의 변경 사항을 배우지 못하면 다음과 같이 누락됩니다.

  • 제네릭
  • 부분
  • 익명의 방법
  • 반복자
  • 널 입력 가능 유형
  • 자동 속성
  • 익명 유형
  • 확장 방법
  • 람다
  • 비동기 메소드

이것은 위키피디아 기사에서 볼 수있는 몇 가지 일반적인 기능입니다. 내가하고 싶은 요점은 개발자가 배우지 않으면 코드베이스가 빈틈없이 유지된다는 것입니다. 완전한 테스트 스위트를 통해 개발자가 지속적으로 개선하고 코드 기반이 발전하기를 바랍니다. .NET 1을 사용하여 수동으로 속성을 구현 한 것이 얼마나 나쁜지 기억하십니까?

Linq는 인생을 더 쉽게 만듭니다. 가능한 곳에서 사용하십시오. 팀원에게 동기를 부여 할 수 있습니다.

그렇다면 패턴은 코드 스타일의 일부로 어느 정도까지 유지되며 일관성 유지와 개선 사이의 경계를 어디에서 그려야합니까?

개선은 점진적입니다. 나에게는 읽기 어렵고 유지 관리가 쉽지 않은 오래된 스타일 코드를 유지하는 것이 의미가 없습니다. 팀원은 글을 쓸 수 없더라도 최소한 현재 진행중인 작업을 수행 할 수 있어야합니다.


2
나는 당신이 말하는 것에 전적으로 동의하지만 내 질문은 새로운 언어 기능과 그것을 배우는 개발자의 책임에 관한 것이 아니라 코드베이스의 비교적 작은 영역 내에서 비슷한 문제를 다른 방식으로 해결하는 더 일반적인 질문입니다. LINQ는 다른 방법으로 문제를 해결하는 좋은 예이므로 LINQ를 언급했습니다. 제 동료는 새로운 언어 기능을 사용하게되어 기쁘지만 그가 작업하는 코드를 거스르지 않는 경우에만 가능합니다.
Robert Johnson

@RobertJohnson 나는 동료에게 유지 보수성이 일관성을 능가한다는 것을 지적 할 것이므로 기존 코드의 "그레인에 맞지 않는 것"이더라도 유지 보수가 용이하다면 그렇게해야합니다. 이전 숙박 DAO를 사용하는 것이 Linq보다 유지 관리가 더 쉽지 않을 것입니다.
Andy

3

일관성이 있어야하지만 이전 코드와 반드시 일치 할 필요는 없습니다. 즉, 팀은 올바른 작업 수행 방식에 동의해야하며 새 코드가 작성되거나 실질적인 변경이 이루어질 때마다 그 방식을 사용해야합니다.

이렇게하면 일관성의 이점을 최대한 활용할 수 있습니다 (특히 코드를 작성하는 사람은 중요하지 않음). 다른 방식으로 작업을 수행하여 팀이 명확한 이점을 얻는다면 여전히 개선 할 수 있습니다.

이상적인 세계에서는 새로운 올바른 방식에 맞게 모든 이전 코드를 다시 작성합니다. 이것은 경제적으로 실행 가능하지 않지만 기술적 인 의미가 있거나 새로운 방법은 더 나은 방법이 아니어야하며 장기 계획은이를 업그레이드해야합니다. 그만한 가치가 없다면, 새로운 방식으로 귀찮게하지 마십시오. 다르게 말하면, 그것을 올바른 것으로 선언하는 새로운 방법에는 분명한 이점이 있어야합니다.


1

예를 들어 프로젝트에서 코드 스타일 을 따르는 것이 중요하다고 생각합니다 . 명명 규칙, 들여 쓰기 등

동료가 이해하지 못하거나 이전에 프로젝트에 사용되지 않았기 때문에 새로운 언어 구성이나 디자인 패턴을 사용하는 데 제한을 두지 않는다는 데 동의하지 않습니다.

물론 이런 것들을 사용하는 데는 충분한 이유가 있어야합니다. 적절한 경우 성능 또는 간결성.


빼기 란 무엇입니까?
ozz

0

현재 디자인 패턴을 맹목적으로 따르는 것이 매우 조심 스러울 것입니다. 물론, 눈에 띄는 단점이없는 경우 항상 코드 기반에서 유사한 패턴을 따라야합니다.

그러나 대부분의 개발자가 기존의 나쁜 패턴을 따르는 것이 "모범 사례"인 것처럼 느끼는 상황에 들어가기가 너무 쉽습니다.

반면에 일관성은 중요합니다. 막대한 코드베이스를 다룰 때 개발자가 코드베이스의 모든 부분을 읽지 않아도 기대할 사항을 알 수 있도록 유사한 패턴을 따르는 것이 매우 유용합니다.

따라서 가능한 경우 개발자가 따라야 할 패턴에 대한 지침을 설정하고 업데이트하는 것이 가장 좋습니다. 이런 식으로 새로운 코드는 다른 새로운 코드와 일치합니다.


-1

우리는 누구나 정식으로 비공식적 인 기술 회의를 정기적으로 개최합니다. 새로운 기술을 찾으면 회의에서 발표합니다. 일반적으로 동료들이 아이디어를 얼마나 잘 받아들이고 이해하는지 잘 알고 있습니다. 이를 통해 코드에 코드를 포함시키는 것이 현명한 지 결정하고, 다른 사람이 암호를 해독 할 수 있도록 도와 주며, 다른 사람이 해당 스타일에 대한 도움이 필요한 경우 '가는 사람'을 설정합니다. 아무도 바퀴를 재발 명하지 않으면 우리는 여전히 통나무 위에서 물건을 끌고 있습니다.


공감대는 무엇입니까?
개미

나는 downvoter가 아니었지만 이것은 실제로 그 질문에 대한 목표는 아닙니다. 코딩 스타일 문제에 대한 토론이 아닌 어떤 것에 든 적용 할 수있는 팀 프로세스입니다. 또한, "바퀴를 재창조"하는 것이 아니라 "바퀴를 발명"을 의미하지 않습니까?

로그가 바퀴의 유형인지 아닌지 의미론이지만 회전, 마찰을 줄이고 표면이지면과 연속적으로 접촉하고 둥글다는 것을 의미합니다. 나는 내가 의미하는 바에 대한 더 좋은 예가 있다고 확신한다. 나는 그것을 독자의 연습으로 남겨 두겠다.
앤트
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.