거대한 접착제 방법을 피하는 방법?


21

현재 직장에서는 몇 번이나 오래된 코드를 정리해야했습니다. 종종 코드는 미로이며 그 뒤에있는 데이터는 훨씬 더 얽혀 있습니다. 나는 멋지고 깔끔한 모듈 방식으로 것들을 빗나가고 있습니다. 각 방법은 한 가지 일을 잘 수행합니다. 그때가 남쪽으로 가기 시작합니다 ...

필자는 항상 깨끗한 API로 끝내고 실제로 묶을 방법이 없습니다. 해결책은 결국 모든 "깨끗한"방법을 호출하는 큰 추악한 "접착제"방법 (일반적으로 조건문으로 가득 찬)을 작성하는 것입니다.

글루 방법은 일반적으로 정리하려고하는 코드 / 데이터 엉킴의 간결한 버전이됩니다. 일반적으로 더 읽기 쉽지만 여전히 성가시다.

그러한 방법을 피하려면 어떻게해야합니까? 이것이 엉킨 데이터의 증상입니까, 아니면 제가 잘못하고있는 것의 반영입니까?


3
API를 사용해야합니다. 엉킨 엉망으로 API를 만든 다음 다시 엉킨 것입니다. 비즈니스 요구 사항 일 수도 있습니다. 그러나 다른 누군가가 API를 사용하여 쉽게 다른 접착제 기능을 만들 수 있기 때문에 가치를 추가했습니다. 손을 ring 필요가 없습니다 ...
Aditya MP

1
우리는 여기서 물건을 말하고 있습니까?
Erik Reppen

3
나는 이것이 그 질문의 복제본이라고 생각하지 않습니다. 저는 좀 더 일반적으로 (그리고 단일 기능보다 더 큰 규모로 말하고 있습니다).
cmhobbs

1
erik-나는 여기서 객체와 메소드에 대해 이야기하고 있습니다. 조건부 혼란을 가져 와서 API로 바꿨습니다. API를 호출 할 때 문제가 발생합니다. 그래도 첫 번째 대답은 내가 찾고있는 것일 수도 있습니다.
cmhobbs 2013

2
지구상에서 그 복제본은 어떻습니까?
MattDavey 2013

답변:


12

LedgerSMB 리팩토링 경험을 드리겠습니다. 우리는 초기에 다르게 일을하기로 결심했지만 여전히 당신이 묘사 한 것을 정확하게 수행하고 있지만 많은 접착제 방법을 사용하지 않고 있습니다 (우리는 많은 접착제 방법을 가지고 있지만 btw는 아닙니다).

두 개의 코드베이스를 가진 삶

LedgerSMB는 약 5 년 동안 두 개의 코드베이스로 살아남 았으며 이전 코드베이스가 제거되기 전에 몇 배 더 늘어날 것입니다. 오래된 코드베이스는 참으로 공포입니다. 나쁜 db 디자인, Perl IS->some_func(\%$some_object);은 스파게티 은유가 때때로 사용되는 이유를 정확히 보여주는 코드와 같이 구성합니다 (모듈과 백, 언어 사이에 운율이나 이유가없는 실행 경로). 새로운 코드베이스는 db 쿼리를 저장 프로 시저로 이동하고 요청 처리를위한보다 깔끔한 프레임 워크 등을 제공하여이를 피합니다.

우리가 가장 먼저 결정한 것은 모듈별로 모듈을 리팩토링하는 것입니다. 즉, 특정 영역의 모든 기능을 새 모듈로 옮긴 다음 이전 코드를 새 모듈에 연결해야합니다. 새로운 API가 깨끗하다면 별 문제가되지 않습니다. 새로운 API가 문제가되지 않으면 새로운 API에서 조금 더 열심히 일하라는 초대입니다 ....

두 번째는 새 코드가 이전 코드의 논리에 액세스해야하는 경우가 많다는 것입니다. 이것은 추한 접착제 방법으로 이어지지 만 항상 피할 수는 없기 때문에 가능한 한 피해야합니다. 이 경우 접착제 방법을 최소화하고 가능한 한 피해야하지만 필요할 때 사용해야합니다.

이 작업을 수행하려면 특정 영역의 모든 기능 을 다시 작성 해야 합니다. 예를 들어, 모든 고객 정보 추적 코드를 한 번에 다시 작성할 수 있으면 이전 코드에서이를 호출하는 코드가 작동하기 어렵고 새 코드에서 이전 코드로 디스패치되는 것이 최소화됩니다.

두 번째로, 합리적인 추상화가 있다면 호출 할 API의 수준과이를 깨끗하게 유지하는 방법을 선택할 수 있어야합니다. 그러나 API를 호출하는 부분을 다시 작성하여 상당히 깨끗하게 생각해야합니다.

매우 복잡한 비즈니스 도구 영역이 많이 있습니다. 모든 복잡성을 제거 할 수는 없습니다. 그러나 특히 필요한 작업을 수행하는 깨끗한 API와 해당 API를 건설적으로 활용하는 모듈에 중점을 두어 관리 할 수 ​​있습니다. 접착제는 나머지 호출 코드를 다시 작성하는 것이 더 빠를 수 있다는 점을 고려한 후에 만 ​​최후의 수단이되어야합니다.


나는 당신이 머리에 못을 박았다고 생각합니다. 접착제가 존재하는 이유는 내가 만든 인터페이스를 호출하는 코드 때문일 수 있습니다. 나는 우리가 무엇을 놓치고 있는지 알기 위해 더 많은 응답을 기다릴 것입니다. 그러나 나는 이것이 이것을 아주 잘 요약한다고 믿습니다.
cmhobbs

1
"동요 나 이유없이 모듈과 언어 사이, 그리고 언어 사이에서 구불 구불 한 실행 경로"-이것은 현대의 일부 OO 관행을 상기시킵니다.
user253751

8

그것은 당신이의 얽힌 혼란 촬영 한 일을 같은 소리 precedural 코드베이스와 사랑스러운 모듈 생성 precedural 코드베이스를.

필자는 항상 깨끗한 API로 끝내고 실제로 묶을 방법이 없습니다. 해결책은 결국 모든 "깨끗한"방법을 호출하는 큰 추악한 "접착제"방법 (일반적으로 조건문으로 가득 찬)을 작성하는 것입니다.

절차 적 코드를 사용하면 (OO로 위장한 경우에도) 항상 어딘가에 정의 된 일종의 순차적 워크 플로로 끝나게되며 종종 설명하는대로 복잡한 조건부 분기로 채워집니다. 코드의 절차 적 특성으로 인해 무언가 잘못되었다고 생각합니다. 이것은 반드시 나쁜 것은 아니며 레거시 코드로 작업 할 때 완전히 피할 수 없을 수도 있습니다


6

원래 코드베이스를 정리하는 것과 같은 방식으로 큰 못생긴 접착제 방법을 정리해야합니다. 깔끔한 모듈 방식으로 분할하십시오. 아마도 일부 작업을 수행하는 코드 줄 그룹이 메소드에서 이러한 줄을 나눕니다. 일부 변수를 공유하면 공유 변수와 새 메소드를 한 클래스에 넣는 것을 고려할 수 있습니다.


2
당신은 접착제 나무를 얻지 않습니까?
피터 B

3
@PieterB 어쩌면 다른 방법으로 다른 작업을 할 때 다른 종속성을 추출하는 것이 더 쉽습니다. 새 메소드를 추출한 후 다른 리팩토링 패스를 수행 할 수 있습니다.
Paling

1

기본적으로 추상화 레이어는 각 레이어를 직접 볼 때까지 계속 추가 합니다. 추상화에 대한 역설적 인 점은 추상화를 줄이는 복잡성을 추가한다는 것입니다. 추상화 된 코드를 읽을 때 한 번에 하나의 계층에만 관심이 있기 때문입니다. 각 층이 이해하기 쉽도록 작은 층이라면, 얼마나 많은 층이 놓여 있는지는 중요하지 않습니다.

또한 추상화를 작성하기가 어렵습니다. 연필 처럼 단순한 것조차도 모든 추상화 계층을 머리에 한 번에 잡으려고하면 마음이 구부러집니다. 핵심은 원하는 방식으로 하나의 레이어를 얻은 다음 해당 레이어의 기본이되는 모든 복잡성을 잊고 다음 단계에서 동일한 작업을 수행하는 것입니다.


0

API 구현에 대해 생각하면 API를 리팩토링하는 것처럼 들리지만 API를 사용하는 코드, 즉 말하는 "접착제 코드"에 대해서는 충분히 생각하지 않아도됩니다.

그것이 사실이라면 다른 쪽 끝에서 시작하려고 할 수 있습니다. 처음에는 못생긴 접착제 코드가 될 수있는 위협 요소를 다시 작성하고 해당 프로세스에서 API가 될 아직 구현되지 않은 인터페이스를 만듭니다. 이 API의 실제 구현에 대해 너무 많이 생각하지 마십시오. 할 수 있다고 생각한다면 괜찮습니다. 그런 다음 코드 미로를 다시 작성하여 해당 API를 준수하십시오. 물론이 프로세스에서 API와 글루 코드에 약간의 변화가 있지만 더 잘 맞아야합니다.

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