명백한 추상화가없는 코드 복제


14

코드 라인을 살펴볼 때 논리에서의 역할을 충실하게 설명하는 주제별 추상화를 적용 할 수없는 코드 복제 사례를 본 적이 있습니까? 그리고 그것을 해결하기 위해 무엇을 했습니까?

코드 복제이므로 이상적으로 자체 기능을 만드는 것과 같이 굴절을 수행해야합니다. 그러나 코드에는 코드를 설명하기에 좋은 추상화가 없기 때문에 결과는 우리가 알 수없는 이상한 기능이 될 것이며 논리를 보는 것만으로는 논리의 역할이 분명하지 않습니다. 그것은 코드의 선명도를 떨어 뜨립니다. 우리는 명확성을 유지하고 그대로 남겨 둘 수 있지만 유지 관리 성이 손상됩니다.

이와 같은 문제를 해결하는 가장 좋은 방법은 무엇이라고 생각하십니까?

답변:


18

때때로 코드 중복은 "pun"의 결과입니다. 두 가지가 동일하게 보이지만 그렇지 않습니다.

과도하게 요약하면 시스템의 실제 모듈성이 손상 될 수 있습니다. 모듈화 체제 하에서 "무엇이 변경 될 가능성이 있습니까?"를 결정해야합니다. "안정적인 것은 무엇입니까?" 안정된 것은 인터페이스에 들어가고 불안정한 것은 모듈의 구현에 캡슐화됩니다. 그런 다음 상황이 변경되면 변경해야 할 사항이 해당 모듈과 분리됩니다.

리팩토링은 안정하다고 생각한 것 (예 :이 API 호출은 항상 두 개의 인수를 취해야 함)을 변경해야 할 때 필요합니다.

따라서이 두 개의 중복 된 코드 조각에 대해 다음과 같이 묻습니다. 하나에 필요한 변경이 반드시 다른 하나도 변경되어야한다는 것을 의미합니까?

그 질문에 어떻게 대답하면 좋은 추상화가 무엇인지에 대한 더 나은 통찰력을 얻을 수 있습니다.

디자인 패턴도 유용한 도구입니다. 아마도 중복 코드가 어떤 형태의 순회를 수행하고 있으며 반복자 패턴을 적용해야 할 것입니다.

중복 된 코드에 여러 개의 반환 값이있는 경우 (단순한 추출 방법을 수행 할 수없는 경우) 반환 된 값을 보유하는 클래스를 만들어야합니다. 이 클래스는 두 코드 조각 사이에서 다른 각 지점에 대해 추상 메서드를 호출 할 수 있습니다. 그런 다음 클래스의 두 가지 구체적인 구현을 수행합니다. 각 조각마다 하나씩. [이것은 효과적으로 템플릿 메소드 디자인 패턴이며 C ++의 템플릿 개념과 혼동되지 않습니다. 또는 전략 패턴으로보고있는 내용을 더 잘 해결할 수도 있습니다.]

그것에 대해 생각하는 또 다른 자연스럽고 유용한 방법은 고차 함수입니다. 예를 들어, 코드를 추상화하기 위해 람다를 만들거나 익명의 내부 클래스를 사용합니다. 일반적으로 복제를 제거 할 수 있지만 실제로 변경이있을 경우 (하나가 변경되면 다른 하나도 변경되지 않는 한) 모듈성을 손상시키지 않을 수 있습니다.


4

이와 같은 상황이 발생하면 "전통적인"추상화에 대해 생각하는 것이 가장 좋습니다. 아마도 함수 내에 중복이 많고 너무 많은 변수를 전달해야하기 때문에 평범한 오래된 함수를 고려하는 것이 적합하지 않을 수 있습니다. 여기서 D / Python 스타일의 중첩 함수 (외부 범위에 액세스 할 수 있음)가 효과적입니다. (예, 모든 상태를 유지하기 위해 클래스를 만들 수는 있지만 두 함수에서만 사용하는 경우 중첩 함수가없는 추악하고 자세한 해결 방법입니다. 상속이 적합하지 않지만 어쩌면 상속 mixin이 잘 작동합니다. 어쩌면 실제로 필요한 것은 매크로 일 것입니다. 아마도 템플릿 메타 프로그래밍, 리플렉션 / Introspection 또는 생성 프로그래밍을 고려해야합니다.

물론 실용적인 관점에서 볼 때, 언어가 언어를 지원하지 않고 언어 내에서 언어를 깨끗하게 구현할 수있는 메타 프로그래밍 기능이 충분하지 않으면 불가능하지는 않지만 어려울 수 있습니다. 이 경우에는 "더 나은 언어 구하기"를 제외하고 무엇을 말해야할지 모르겠습니다. 또한 Ruby, Python, Lisp 또는 D와 같은 추상화 기능이 많은 고급 언어를 학습하면 일부 기술은 여전히 ​​사용 가능하지만 명확하지 않은 하위 언어로 더 잘 프로그래밍 할 수 있습니다.


좁은 공간에 압축 된 뛰어난 기술을 많이 얻으려면 +1하십시오. (음, 설명 된 기술에 대해서도 +1이되었을 것입니다.)
Macneil

3

개인적으로 나는 그것을 무시하고 계속합니다. 그것이 이상한 경우라면 그것을 복제하는 것이 낫다면, 당신은 나이를 리팩토링 할 수 있고 다음 개발자는 한 번 살펴보고 변경을 취소 할 것입니다!


2

코드 샘플이 없으면 코드에 식별 가능한 추상화가없는 이유를 말하기가 어렵습니다. 이 경고와 함께 몇 가지 아이디어가 있습니다.

  • 공통 코드를 유지하기 위해 하나의 새로운 함수를 작성하는 대신 기능을 여러 개의 고유 한 조각으로 나눕니다.
  • 일반적인 데이터 유형 또는 추상 동작에 따라 작은 조각을 그룹화합니다.
  • 새로운 조각이 주어진 중복 코드를 다시 작성하십시오.
  • 새 코드가 여전히 명확한 추상화를 거부하는 경우 코드를 작게 나누고 프로세스를 반복하십시오.

이 연습에서 가장 큰 어려움은 함수가 주어진 추상화 수준에서 관련이없는 동작을 너무 많이 통합했을 가능성이 높으며 그 중 일부는 낮은 수준에서 처리해야한다는 것입니다. 명확성은 코드를 유지 관리하는 데 중요하지만 코드의 동작을 명확하게하는 (현재 상태) 코드의 의도를 명확하게하는 것과는 매우 다릅니다.

함수 서명이 무엇을 식별하도록하여 더 작은 코드 조각을 추상화하는 방법을 만들고 더 큰 조각을 쉽게 분류 할 수 있어야합니다.

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