어떤 경우에 코드가 적을수록 좋지 않습니까? [닫은] 내가 잘했다고 생각했습니다. 980 줄의 코드를 450으로

나는 최근에 직장에서 일부 코드를 리팩터링했으며, 내가 잘했다고 생각했습니다. 980 줄의 코드를 450으로 떨어 뜨리고 클래스 수를 반으로 줄였습니다.

이것을 내 동료들에게 보여줄 때 일부는 이것이 개선이라는 데 동의하지 않았습니다.

그들은 “몇 줄의 코드가 반드시 더 나은 것은 아니다”고 말했다.

사람들이 정말로 긴 줄을 쓰거나 모든 것을 하나의 방법으로 작성하여 몇 줄을 저장하는 극단적 인 경우가있을 수 있지만 이것이 내가 한 것이 아닙니다. 내 생각에 코드는 크기가 절반이므로 이해하기 쉽고 체계적으로 구성되어 있습니다.

왜 누군가가 작업을 수행하는 데 필요한 코드의 두 배로 작업하고 싶어하는지 이해하기 위해 고심하고 있습니다. 누군가가 내 동료와 같은 느낌을 느끼고 더 적은 코드를 더 많이 사용하는 좋은 사례를 만들 수 있는지 궁금합니다. ?



답변

얇은 사람이 과체중 사람보다 반드시 건강하지는 않습니다.

980 줄의 어린이 이야기는 450 줄의 물리학 논문보다 읽기 쉽습니다.

코드의 품질을 결정하는 많은 속성이 있습니다. Cyclomatic ComplexityHalstead Complexity 와 같은 일부는 단순히 계산됩니다 . 응집력 , 가독성, 이해도, 확장 성, 견고성, 정확성, 자체 문서화, 청결도, 테스트 가능성 등과 같은 다른 것들도 더 느슨하게 정의됩니다 .

예를 들어 코드의 전체 길이를 줄이면서 불필요하게 복잡성을 추가하고 코드를 더 암호로 만들 수 있습니다.

긴 코드 조각을 작은 방법 으로 나누면 유익 할 수있는만큼 해로울 수 있습니다 .

리팩토링 노력이 바람직하지 않은 결과를 낳았다 고 생각하는 이유에 대한 구체적인 피드백을 동료에게 제공하도록 요청하십시오.


답변

흥미롭게도, 동료와 나는 현재 코드 라인이 동일하게 유지되지만 클래스와 함수의 수를 두 배 미만으로 늘리는 리 팩터의 중간에 있습니다. 좋은 예가 있습니다.

우리의 경우에는 실제로 2 개가되어야 할 추상화 계층이 1 개있었습니다. 모든 것이 UI 레이어에 들어갔습니다. 이를 두 개의 계층으로 나누면 모든 것이 더 응집력이 높아지고 개별 조각을 테스트하고 유지 관리하는 것이 훨씬 간단 해집니다.

동료를 괴롭히는 코드 의 크기 가 아니라 다른 것입니다. 그들이 그것을 표현할 수 없다면, 이전 구현을 본 적이없는 것처럼 코드를 직접보고 비교하기보다는 자체 장점으로 평가하십시오. 때로는 긴 리팩터링을 할 때 원래 목표를 잊어 버리고 너무 멀리 가져갑니다. 중요한 “큰 그림”을보고 조언을 소중히 여기는 페어 프로그래머의 도움을 받아 다시 제자리에 놓으십시오.


답변

알버트 아인슈타인 (Albert Einstein)으로 여겨지는 인용구는 다음과 같습니다.

모든 것을 가능한 한 단순하게 만드십시오.

물건을 다듬을 때 선외로 가면 코드를 읽기가 더 어려워 질 수 있습니다. “쉬운 / 읽기 어려운”은 매우 주관적인 용어 일 수 있으므로, 이것이 의미하는 바를 정확하게 설명하겠습니다. 숙련 된 개발자가 “이 코드의 기능”을 결정하는 데 어려움이 얼마나 있을까요? 전문화 된 도구의 도움없이 소스 만 살펴보면됩니다.

Java 및 Pascal과 같은 언어는 자세한 설명으로 유명하지 않습니다. 사람들은 종종 특정 구문 요소를 가리키며 “컴파일러의 작업을 더 쉽게하기 위해 거기에 있습니다”라고 비난 적으로 말합니다. 이것은 “단지”부분을 제외하고는 다소 사실입니다. 명확한 정보가 많을수록 컴파일러뿐만 아니라 인간이 코드를 읽고 이해하기가 더 쉽습니다.

내가 말하면 정수라는 것이 var x = 2 + 2;즉시 분명합니다 x. 그러나 내가 말하면 var foo = value.Response;, 그것이 무엇을 foo나타내는 지 또는 그 속성과 기능이 무엇 인지 는 훨씬 명확하지 않습니다 . 컴파일러가 쉽게 추론 할 수 있어도 사람에게 훨씬 더인지적인 노력을 기울입니다.

사람들이 읽을 수 있도록, 그리고 기계가 실행할 수 있도록 프로그램을 작성해야합니다. (이론적으로,이 인용문은 극도로 읽기 어려운 악명 높은 언어로 쓰여진 교과서에서 나옵니다!) 중복되는 것을 제거하는 것이 좋습니다. 프로그램을 작성하는 데 꼭 필요한 것은 아니지만 진행 상황을 파악하십시오.


답변

더 긴 코드는 더 읽기 쉽습니다. 일반적으로 반대이지만 많은 예외가 있습니다. 그중 일부는 다른 답변에 요약되어 있습니다.

그러나 다른 각도에서 보자. 우리는 회사의 문화, 코드 기반 또는 로드맵에 대한 추가 지식 없이도 2 개의 코드를 보는 대부분의 숙련 된 프로그래머가 새 코드를 우수한 것으로 간주합니다. 그럼에도 불구하고 새로운 코드를 반대해야 할 많은 이유가 있습니다. 간결하게하기 위해 “새 코드를 비판하는 사람들” Pecritenc이라고합니다 .

  • 안정. 이전 코드가 안정적인 것으로 알려진 경우 새 코드의 안정성을 알 수 없습니다. 새 코드를 사용하려면 여전히 테스트해야합니다. 어떤 이유로 적절한 테스트를 사용할 수없는 경우 변경이 큰 문제입니다. 테스트가 가능하더라도 Pecritenc은 노력이 코드의 (사소한) 개선 가치가 없다고 생각할 수 있습니다.
  • 성능 / 확장. 이전 코드는 더 잘 확장되었을 수 있으며 Pecritenc은 클라이언트와 기능이 곧 쌓이면서 성능이 문제가 될 것이라고 가정합니다.
  • 확장 성. 이전 코드는 Pecritenc이 곧 추가 할 것으로 예상되는 일부 기능을 쉽게 소개 할 수있었습니다.
  • 정통. 이전 코드는 회사 코드베이스의 다른 5 개 장소에서 사용되는 재사용 패턴을 가질 수 있습니다. 동시에 새로운 코드는 회사의 절반 만이 시점에서 들어 본 멋진 패턴을 사용합니다.
  • 돼지에 립스틱. Pecritenc은 이전 코드와 새 코드가 모두 쓰레기이거나 관련이 없다고 생각할 수 있으며, 따라서 이들 코드를 비교할 때 무의미합니다.
  • 자부심. Pecritenc은 코드의 원작자 일 수 있으며 사람들이 코드를 크게 변경하는 것을 좋아하지 않습니다. 그는 개선이 가벼운 모욕으로 보일 수도 있습니다. 왜냐하면 그들이 더 잘했음을 암시하기 때문입니다.

답변

어떤 종류의 코드가 더 좋은지는 프로그래머의 전문 지식과 그들이 사용하는 도구에 달려 있습니다. 예를 들어, 다음은 일반적으로 잘 작성되지 않은 코드로 간주되는 것이 상속을 최대한 활용하는 잘 작성된 객체 지향 코드보다 일부 상황에서 더 효과적인 이유입니다.

(1) 일부 프로그래머는 객체 지향 프로그래밍을 직관적으로 파악하지 못합니다. 소프트웨어 프로젝트에 대한 은유가 전기 회로라면 많은 코드 복제가 필요합니다. 많은 클래스에서 거의 동일한 메소드를 보려고합니다. 그들은 당신이 집에서 느끼게합니다. 그리고 부모 클래스 나 조부모 클래스에서 메소드를 찾아보아야하는 프로젝트가 진행 상황을 적대적으로 느낄 수 있습니다. 부모 클래스의 작동 방식을 이해하고 현재 클래스의 차이점을 이해하고 싶지 않습니다. 현재 클래스의 작동 방식을 직접 이해하려고하며 정보가 여러 파일에 혼동되어 있다는 사실을 알게됩니다.

또한 특정 클래스의 특정 문제를 해결하려는 경우 기본 클래스에서 직접 문제를 해결하거나 현재 관심있는 클래스의 메서드를 덮어 쓸지 여부를 생각하고 싶지 않을 수 있습니다. 상속 없이는 의식적인 결정을 내릴 필요가 없습니다. 기본값은 비슷한 클래스에서 비슷한 문제가 버그로보고 될 때까지 무시하는 것입니다. 반대.

(2) 일부 프로그래머는 디버거를 많이 사용합니다. 일반적으로 나는 코드 상속 측면에서 확고하고 복제 방지 측면에서도 확실하지만 객체 지향 코드를 디버깅 할 때 (1)에서 설명한 좌절감을 공유합니다. 코드 실행을 수행하면 동일한 객체에 남아 있어도 때때로 (조상) 클래스 사이를 계속 뛰어 다닙니다. 또한 잘 작성된 코드에서 중단 점을 설정하면 도움이되지 않을 때 트리거 될 가능성이 높아 지므로 조건부 (실제적인 경우)로 만들거나 관련 트리거 전에 수동으로 여러 번 계속하는 데 노력해야 할 수도 있습니다.


답변

그것은 전적으로 달려 있습니다. 부울 변수를 함수 매개 변수로 허용하지 않지만 대신 enum각 옵션에 대한 전용이 필요한 프로젝트를 진행했습니다 .

그래서,

enum OPTION1 { OPTION1_OFF, OPTION1_ON };
enum OPTION2 { OPTION2_OFF, OPTION2_ON };

void doSomething(OPTION1, OPTION2);

보다 더 장황하다

void doSomething(bool, bool);

하나,

doSomething(OPTION1_ON, OPTION2_OFF);

보다 더 읽기 쉽다

doSomething(true, false);

컴파일러는 두 코드에 대해 동일한 코드를 생성해야하므로 더 짧은 형식을 사용하여 얻을 수있는 것은 없습니다.


답변

응집력이 문제가 될 수 있다고 말하고 싶습니다.

예를 들어 웹 응용 프로그램에서 모든 제품을 색인하는 관리 페이지가 있다고 가정 해 봅시다. 모든 제품은 홈페이지 상황에서 사용하는 코드와 동일한 코드 (인덱스)입니다.

DRY를 유지하고 매끄럽게 유지하기 위해 모든 것을 부분 화하기로 결정한 경우 사용자 탐색이 관리자인지 아닌지에 관한 많은 조건을 추가하고 불필요한 내용으로 코드를 어지럽히면 읽을 수 없게됩니다. 디자이너!

따라서 이와 같은 상황에서는 코드가 거의 동일하더라도 다른 것으로 확장 될 수 있고 사용 사례가 약간 변경 될 수 있기 때문에 조건과 if를 추가하여 각각을 따라가는 것은 좋지 않습니다. 따라서 DRY 개념을 버리고 코드를 유지 관리 가능한 부분으로 나누는 것이 좋은 전략입니다.