2010-06-03 2 views
0

레거시 코드를 유지 관리하는 일환으로 설계의 일부를 주로 테스트 할 수 있도록 변경해야합니다 (단위 테스트). 해결해야 할 문제 중 하나는 구성 요소 간의 기존 인터페이스입니다. 두 구성 요소 사이의 인터페이스는 정적 메서드 만 포함하는 클래스입니다.인터페이스 재 설계에 대한 제안 받기

간단한 예 :

class ABInterface { 

    static methodA(); 
    static methodB(); 
    ... 
    static methodZ(); 
}; 

다른 방법은 일부 입력 데이터를 준비하기 위해 ABInterface :: methodA()을 사용하고 성분 B.

내에 해당 함수를 호출 할 수 있도록 인터페이스를 성분 (A)로 사용되는

이제 우리는 여러 가지 이유로이 인터페이스 재 설계하기 위해 노력하고있다 : 우리의 단위 테스트 범위를 확장

  • 을 - 우리가 입술에 필요 이 구성 요소와 스텁/모의 객체 간의 의존성을 도입해야한다.

  • 원래의 설계와 다른 인터페이스 (예 : 컴포넌트 간 i/f에 사용되는 많은 새로운 함수가이 인터페이스 클래스 외부에서 생성됩니다.

  • 코드가 오래되었습니다. 시간이 지나면 많이 변경되어 리팩토링해야합니다.

변경 내용이 나머지 시스템에 영향을주지 않아야합니다. 우리는 많은 테스트 요구 아티팩트를 프로덕션 코드에 그대로 두려고합니다. 성능은 매우 중요하며 재 설계 후 성능 저하가 없어야합니다. C++에서는 코드가 OO입니다.

나는 어떤 접근 방식을 택할 것입니까? 이 작업을 효율적으로 수행하는 방법에 대한 제안 사항은 무엇입니까?

+0

는 하나의 클래스 인터페이스는 매우 유용하지 않습니다. 오히려 일종의 "경량"uml 다이어그램이 필요합니다. 리팩터링을 제대로하기 위해서는 필요한 정보의 흐름입니다. –

+0

이것은 하나의 인터페이스 클래스이고 그 정적 메소드는 컴포넌트 A에서 컴포넌트 B로 올바른 호출을하기 위해 사용됩니다. 두 컴포넌트는 단지 2 개의 클래스가 아니라 라이브러리입니다. 정보의 흐름 - 성분 A에서있어서, 상기 인터페이스 클래스의 정적 메소드를 사용하여 입력 PARAMS 하나 이상의 채워지 적절한 리턴 코드에 다시 복귀하고, 어떤 계산이 수행되어 B에서 B.에서 메소드를 호출 A.에있는 호출 함수는 이것이 더 나은 흐름을 설명하기를 바란다. (나는 어떤 움틀도 준비가되어 있지 않다.) – ratkok

답변

1

가장 간단한 대답은, 외관의 정적 인터페이스가 기존 라이브러리를 래핑 기존 라이브러리 대신 새로운 외관을 호출하는 코드를 리팩토링하는 것입니다. 이 새로운 쐐기는 단위 테스트 목적으로 도서관을 대체 할 수 있어야합니다. 첫 번째 방법을 테스트 해보고 구현 방법을 확인하십시오. 질문에 "성능 문제"로 오염되었을 때 정말 날 귀찮게 무엇

이다. 우리는 모두 중요한 성능 코드를 작성했으며 성능이 좋지 않은 코드 작성을 의도적으로 제안한 사람은 없습니다. 나는이 "관심사"가 대개 모든 변화를 비판하는 불신자들로부터 왔으며 실제로 어떤 변화가 잘 수행 될지 또는 그렇지 않을 것인지에 대한 단서를 실제로 가지고 있지 않다는 것을 안다. 성능의 유일하게 유효한 증거는 테스트에서 비롯된 것임을 기억하십시오. 성능 테스트를 실행하고 기준선을 설정하십시오. 변경하십시오. 새 코드에서 성능 테스트를 다시 실행하십시오. 실제 영향을 보여줍니다. 그래야만 변화의 실제 영향에 대한 결정을 내릴 수 있습니다. never 다른 방법으로 설명 될 때까지 디자인에서 우위를 차지할 수 있습니다.

그것은 프로젝트에 중요한 사람처럼 * 얼마 전 일부 시끄럽게 지껄이는 놈이 같은 말을 들었다 오래된 C 프로그래머입니다 소리 "C 빠른 실행 ++ 만드는 유일한 방법은 정적 인 방법을 사용하는 것입니다가." 문제는 그가 여전히 그것을 믿는다는 것이다. 20 년 전 웅대 한 사운드가 옳았지만 20 년 동안 컴파일러와 옵티 마이저가 크게 개선되었습니다. 그래서 변화를 시도하십시오.

현대 컴파일러를 사용하는 경우 옵티마이 저는 어쨌든 오브젝트 코드의 여분의 역 참조를 제거하므로 런타임에 아무런 영향을 미치지 않을 가능성이 있습니다.

성능이 모두 중요하지만 성능 테스트가 없거나 최신 컴파일러를 사용하지 않거나 모든 릴리스 빌드 최적화가 조정되지 않은 경우 (프로필 유도 최적화 사용) 예를 들어,) 추상화의 추가 레이어의 성능에 대해 걱정하기 오래 전에 신경 써야 할 훨씬 더 큰 엔지니어링 문제가 있습니다.

  • 참고 : 나는 또한 20 년 전 그런 바보 같은 말을하는 오래된 C 프로그래머입니다. 차이점은 몇 가지 최적화가 다른 것보다 훨씬 더 중요하다는 것을 배웠고, 새로운 컴파일러는 대부분의 것들을 스스로 알아내는 데 놀랍도록 훌륭하다는 것입니다. 조만간 일을 "최적화"하려는 나의 시도는 대개 재고 컴파일러 설정보다 성능이 좋지 않은 비싼 유지 보수 코드로 끝납니다. 리팩토링 조언을 들어
+0

제안에 감사드립니다.나는 당신이 성능에 영향을주지 않는다는 것에 동의하지만 어느 정도는 그렇다. 성능 영향은 일반화 될 수 없으며 실제로 다른 일부 작업에도 영향을받습니다. 그러나 현대의 컴파일러는 최적화를 수행하고 대다수의 경우에서 눈에 띄는 성능 저하를 제거합니다. – ratkok

0

methodsA-Z가 정적이 아니고 가상 일 경우 쉽게 수정할 수 있습니까? 따라서 정적 methodA-Z가 비 정적, 가상 methodA-Z를 호출하는 경우 동작을 재정의 할 수 있습니다. 이것을 알면 테스트를 위해 비 정적 버전을 포함하는 인스턴스를 변경하는 방법이 필요합니다.

또는 리팩터링하려는 두 클래스를 가져 와서이 정적 전용 클래스에 래퍼를 사용할 수 있습니다. 그러면 두 사람은 필요한만큼 갈라질 수 있습니다.

실제 문제를 보지 않고도 내 모든 아이디어에 관한 내용입니다.

+0

예, 메서드가 비 정적 인 경우 - 쉽습니다. 정적 클래스에서 호출 된 새로운 가상 함수 집합 (정적 클래스에서 호출 됨)을 추가하고이 클래스에서 difernet 구현을 제공하고 테스트시 인스턴스화되고 사용될 수있는 새 클래스를 파생시키는 것이 좋습니다. 대안을 잘 모르겠습니다. 어쩌면 내가 원래의 질문에 분명하지 않았던 것 - 구성 요소는 단지 2 개의 클래스가 아니라 오히려 라이브러리/모듈 – ratkok

0

답변 및 의견을 보내 주셔서 감사합니다. 정적 메소드 대체/포장하기 -

  • 인스턴스 위임자가 :

    Working Effectively with Legacy Code 책, 다음과 같은 두 가지 기술의 조합에서 "종속성-속보 기술"장을 검토 한 후 실제로 우리의 문제에 대한 해결책이 될 것 같다 새로운 가상 메소드가있는 유틸리티 클래스에서.

  • 정적 설정자 - 다른 유틸리티 클래스 (프로덕션 코드 또는 스텁 코드)를 인스턴스화 할 수 있습니다.

이 두 가지를 결합하면 테스트중인 구성 요소를 나머지 제품 코드와 분리 할 수 ​​있습니다.

우리의 유일한 관심사는 지금 (때문에 가상 함수의 사용) 성능 저하입니다.

관련 문제