건조 원칙 위반


10

이 반 패턴의 이름이 어딘가에있을 것입니다. 그러나 나는 반 패턴 문헌에 대해 잘 알지 못한다.

다음 시나리오를 고려하십시오.

or0클래스의 멤버 함수입니다. 더 좋든 나쁘 든 클래스 멤버 변수에 크게 의존합니다. 프로그래머 A가 와서을 or0호출하는 대신 기능이 필요합니다 or0. 프로그래머 A는 전체 클래스를 복사하고 이름을 바꿉니다. 내가 or0말했듯이, 기능에 대한 멤버 변수에 크게 의존하기 때문에 그녀가 전화하지 않는 것 같습니다. 또는 주니어 프로그래머 일 수도 있고 다른 코드에서 호출하는 방법을 모를 수도 있습니다. 그래서 지금 우리가 가지고 or0c0(복사 C). 이 접근법에 대해 프로그래머 A를 완전히 비난 할 수는 없습니다. 우리 모두는 마감일이 촉박하며 작업을 완료하기 위해 코드를 해킹합니다.

여러 프로그래머가 유지 or0하므로 이제 버전 orN입니다. c0이제 버전 cN입니다. 불행히도 클래스를 포함하는 대부분의 프로그래머는 or0완전히 알지 못하는 것 같았습니다 c0.DRY 원칙의 지혜에 대해 내가 생각할 수있는 가장 강력한 주장 중 하나입니다. 에 코드를 독립적으로 유지 관리했을 수도 있습니다 c. 어느 쪽이든이 나타납니다 or0c0서로 독립적으로 유지되었다. 그리고 기쁨과 행복,에서 cN일어나지 않는 오류가 발생하고 있습니다 orN.

그래서 몇 가지 질문이 있습니다.

1.)이 안티 패턴의 이름이 있습니까? 나는 이것이 너무 자주 일어나는 것을 보았는데 이것이 안티 패턴이 아니라는 것을 믿기 어려울 것입니다.

2.) 몇 가지 대안을 볼 수 있습니다.

a.) orN필요한 모든 멤버 변수의 값을 지정하는 매개 변수를 사용하도록 수정 했습니다. 그런 다음 전달 된 모든 필수 매개 변수 cN를 호출 하도록 수정하십시오 orN.

b.) 수동으로 수정 프로그램을에서 orN로 포트하십시오 cN. (나는 이것을하고 싶지 않지만 현실적인 가능성이다.)

c.) orN- cN다시, 다시 말해, 나는 완전성을 기하기 위해 그것을 다시 언급한다.

d.) cN고장난 곳 을 찾아서 독립적으로 수리하십시오 orN.

대안 장기적으로 가장 좋은 해결책 인 것처럼 보이지만 고객이 구현할 수는 없을 것입니다. 문제를 바로 잡기 위해 시간이나 돈을 쓰지 말고 항상 같은 문제를 40 번이나 50 번 정도 고치는 데 시간과 돈이 필요합니까?

아무도 내가 고려하지 않은 다른 접근법을 제안 할 수 있습니까?


"이 안티 패턴의 이름이 있습니까?" '위반 건조'안티 패턴? :) IMHO 당신은 거의 스스로 대답했습니다.
Steven Jeuris

어쩌면 "드라이 바이올 레이터"라고 불러?
FrustratedWithFormsDesigner

2
나는 그것을 부른다 : 드라이 범핑.
AJC

5
복사 및 붙여 넣기 코딩?
tylermac

그것은 "너무 많은 요리사가 국물을 망친다"패턴이라고 불립니다.
Doc Brown

답변:


18
  1. 그것은 단지 중복 코드 라고 불립니다 . 이것에 대한 더 멋진 이름을 모르겠습니다. 장기적인 결과는 당신이 묘사 한 바와 같으며 더 나쁩니다.

  2. 물론 중복을 제거하는 것이 가능한 경우 이상적인 옵션입니다. 시간이 오래 걸릴 수 있습니다 (최근의 경우 레거시 프로젝트의 경우 클래스 계층 구조에서 20 개가 넘는 서브 클래스에 걸쳐 여러 메소드가 중복되어 있었으며, 그 중 다수는 수년에 걸쳐 자체적으로 약간의 차이 / 확장을 발전 시켰습니다. 모든 중복을 제거하기 위해 연속적인 단위 테스트 작성 및 리팩토링을 통해 약 1.5 년이 걸렸습니다.

    이 경우 중복 제거를 시작하기로 결정하더라도 임시 수정 사항으로 다른 옵션 중 하나 이상이 여전히 필요할 수 있습니다. 그러나 그 중 더 좋은 것은 많은 요인에 달려 있으며 더 많은 맥락이 없다면 우리는 추측하고 있습니다.

    많은 작은 개선이 장기적으로 큰 차이를 만들 수 있습니다. 이러한 클래스에 대한 고객의 명시적인 승인이 반드시 필요한 것은 아닙니다. 버그를 수정하거나 기능을 구현하기 위해 해당 클래스를 터치 할 때마다 약간의 리팩토링이 시간이 지남에 따라 먼 길을 갈 수 있습니다. 작업 견적에 리팩토링을위한 추가 시간을 포함하십시오. 소프트웨어를 장기적으로 건강하게 유지하는 것은 표준 유지 관리와 같습니다.


3
+1, 중복 코드 언급뿐만 아니라 코드 리팩토링 이야기와 관련된 엄청난 노력에도 도움이됩니다. : D
Andreas Johansson

9

WET (We Enjoy Typing) 패턴에 대한 참조가 있지만 표준 이름인지는 모르겠습니다.

... 소프트웨어 라이센싱은 DRY (Do n't Repeat Yourself) 사례에서 두드러진 예외입니다. 소프트웨어 라이센싱 코드는 가능한 한 WET (타이핑을 즐기십시오-DRY와 반대)이어야합니다.

라이센싱 논리를 다른 문제와 분리하여 한 곳에서 격리하는 경우 라이센싱을 완전히 비활성화하기 위해 소프트웨어를 훨씬 쉽게 수정할 수 있습니다. 응용 프로그램 전체에서 라이센싱 논리를 여러 번 반복하는 것이 좋습니다. 소프트웨어의 단일 실행 전체에서 여러 번 실행되는 것이 좋습니다.

예를 들어, 설치 중, 응용 프로그램 시작 중 및 중요한 기능에 액세스 할 때마다 라이센스 검사를 수행하는 것이 좋습니다. 시작하는 동안 라이센스를 한 번 확인하지 말고 해당 값을 전달하십시오. 대신 실제로 각 영역에서 라이센스 확인을 복제하십시오. 불편하지만 깨지기 쉬운 제품을 출시하는 것보다 훨씬 낫습니다.


3
WET는 의미 할 수있다 : 쓰기 모든 회
StuperUser

1
@StuperUser 어제 dailywtf에서 발견했습니다 ...
jeremy-george

3

제대로 이해하면 수업에 너무 많은 일이 있습니다. 이것은 단일 책임 원칙을 따르지 않는 방법을 만듭니다 . 이동해야 할 코드로 이어지고 다른 코드는 생략됩니다. 이것은 또한 많은 회원을 만들 수 있습니다.

내게 필요한 옵션 수정자를 검토해야합니다. 공개 된 것들을 실제로 공개해야합니다. 소비자는 모든 작은 구성원에 대해 알 필요가 없습니다. 캡슐화를 사용하십시오.

이것은 리 팩터를 요구합니다. 또한 사전 설계없이 코드를 작성중인 것으로 보입니다. 테스트 주도 개발을 살펴보십시오. 코드를 호출하는 대신 코드를 어떻게 호출해야하는지 코드를 작성하십시오. 로 봐 TDD 작업을 수행하는 방법에 대한 몇 가지 힌트.


3

코드를 복사하는 경우 이중 유지 보수 또는보다 구체적으로 코드 중복 이라는 기술적 부채가 발생 합니다.

일반적으로 이것은 리팩토링을 통해 수정됩니다. 보다 구체적으로 모든 호출을 공통 코드가있는 새 함수 (또는 새 클래스의 새 메소드)로 리디렉션합니다. 시작하는 가장 쉬운 방법은 복사 된 코드를 모두 제거하고 중단 된 부분을 확인하는 것입니다.이 코드에서 호출을 공통 코드로 리디렉션하여 수정합니다.

기술 전문가가 아닌 사람이 기술 부채를 해결하도록 설득하기 어렵 기 때문에 고객이 코드 리 팩터에 동의하도록하는 것은 어려울 수 있습니다. 다음에 예상 시간을 계산할 때는 예상 값 을 리팩토링하는 데 걸리는 시간포함하십시오 . 대부분의 경우 고객은 수정 작업을 수행하는 동안 코드 정리를 수행한다고 가정합니다.


1

나에게 스파게티 코드 처럼 들린다 . 가장 좋은 수정은 리 팩터 / 다시 쓰기입니다.

복잡하고 복잡한 제어 구조, 특히 많은 GOTO, 예외, 스레드 또는 기타 "구조화되지 않은"분기 구조를 사용하는 제어 구조를 갖는 소스 코드에 대한 용어. 프로그램 흐름이 개념적으로 스파게티 한 그릇과 같이 꼬여서 엉켜 있기 때문에 이름이 지어졌습니다.

http://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Spaghetti.jpg/175px-Spaghetti.jpg


-1 리팩터링과 재 작성은 매우 다른 두 가지 옵션입니다. 소프트웨어를 버리는 전체 재 작성은 결코 좋은 생각이 아닙니다. joelonsoftware.com/articles/fog0000000069.html
P.Brian.Mackey

1
스파게티 코드 는 IMO가 훨씬 일반적이고 느슨한 용어입니다. 이러한 코드에는 종종 중복이 포함되어 있지만 중복없이 스파게티 코드를 만들 수 있지만 스파게티 코드는 많이 복제되지는 않습니다.
Péter Török

@ P.Brian.Mackey 리 팩터와 다시 쓰기가 같은 것이라고 말한 적이 없습니다. OP는 사용할 것을 결정해야합니다.
Tom Squires

2
나는 그 기사의 팬이 아니었다. 나는 재 작성이 인용 된 예에서 나쁜 아이디어라는 것에 동의하지만, 그 사례에서 그것이 나쁜 아이디어라고해서 이것이 항상 나쁜 아이디어라는 것을 의미하지는 않습니다 . 우선 재 작성을 수행하면 다른 진행 상황이 차단됩니까? 그렇다면, 그것은 나쁘다; 그렇지 않다면, 그다지 나쁘지 않습니다.
jhocking

@jhocking-다시 쓰기 금지 정책의 요점은 다른 프로그램의 진행을 차단하는 것이 아니라 시간이 지남에 따라 실제 수정 사항이 손실되는 것입니다. 그 마법의 "if (goldenNugget> 22)"는 이름이 잘못되었지만 여전히 몇 시간 또는 며칠의 연구 없이는 식별 할 수없는 특정 문제를 해결합니다. 이제 동일한 데이터를 가져 와서 개선해야합니다. 그것은 리 팩터입니다. 그것을 버리고 "다음에 바로 할 것"이라고 말하는 것은 시간 낭비입니다. 이미 해결 된 문제를 해결하는 것과 동일한 이유는 시간 낭비입니다. 나쁜 증가 위에 좋은 코드를 추가하면 부채가 증가합니다
P.Brian.Mackey

0

당신은 A를 완전히 비난 할 수 없다고 말하지만, 이런 식으로 수업을 복사하는 것은 실제로 용서할 수 없습니다. 코드 검토 프로세스에서 엄청난 실패입니다. 코드 검토가 전혀없는 가장 큰 실패 일 수 있습니다.

마감일을 맞추기 위해 끔찍한 코드를 만들어야한다고 생각되면 그 이후 릴리스에 대한 절대 우선 순위 요청이 끔찍한 코드를 수정해야합니다. 그래서 당신의 문제는 사라졌습니다.

DRY 원칙은 완벽하지 않고 개선 될 수있는 상황을위한 것입니다. 클래스를 복제하는 것은 완전히 새로운 구경입니다. 나는 먼저 이것을 "중복 코드"라고 부르고, 시간이 지남에 따라 최악의 시간 낭비 자, "발산 중복 코드"로 바뀔 것입니다. 차이점은 의도, 우연 또는 버그입니다.


-3

이 파티에 거의 10 년이 늦었지만이 반 패턴의 이름은 Divergent Change로 , 여러 클래스에 동일한 동작의 사본이 포함되지만 시간과 유지 보수가 진행되고 일부 클래스가 잊혀지면 해당 동작이 분기됩니다.

공유 동작의 정의와 공유 방식에 따라 Shotgun Surgery 로 불릴 수 있는데 , 여기서는 단일 논리 기능이 단일 클래스가 아닌 많은 클래스에 의해 제공된다는 차이점이 있습니다.


1
이것은 같은 것으로 보이지 않습니다. 분기 변경은 같은 클래스에 많은 변경이있을 때입니다. OP는 코드 복제를 설명합니다. 샷건 수술도 같은 것이 아닙니다. Shotgun Surgery는 여러 클래스에 대해 동일한 변경 사항을 설명합니다.
Robert Harvey
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.