레거시 코드베이스에서 사용중인 것과 그렇지 않은 것을 어떻게 빨리 찾을 수 있습니까?


21

나는 그 코드베이스를 유지하는 계약을 맺는 선구자로서 실질적인 레거시 코드베이스로 보이는 것을 평가하도록 요청 받았다.

이 상황에 처한 것은 이번이 처음이 아닙니다. 현재,이 코드는 합리적으로 높은 프로필과 상당히 높은로드의 멀티 플레이어 게임 사이트를위한 것이며, 한 번에 수천 명 이상의 플레이어를 온라인으로 지원합니다. 이러한 사이트가 많기 때문에이 사이트는 프론트 엔드 및 백엔드 기술이 혼합 된 것입니다.

내부에서 본 사이트 구조는 엉망입니다. "_OLD"및 "_DELETE"접미사가있는 폴더가 여기 저기 있습니다. 많은 폴더가 목적에 맞지 않거나 매우 비밀스러운 이름을 가지고 있습니다. 합법적으로 보이는 폴더에도 오래되고 사용되지 않는 오래된 스크립트가있을 수 있습니다. 뿐만 아니라 다른 운영 스크립트에서도 의심의 여지없이 많은 코드 섹션이 있습니다 (훨씬 덜 긴급한 관심사).

이는 기존 유지 관리 담당자로부터 사이트의 원래 개발자 / 관리자로 다시 전달됩니다. 이러한 종류의 시나리오에서 이해할 수 있듯이, 현직 직원은 계약을 합법적으로 요구하여 새로 선출 된 관리자에게 전달하는 것 이외의 다른 방법으로 이양과 관련이있는 것을 원하지 않습니다. 따라서 기존 사이트에서 기존 사이트 구조에 대한 정보를 추출하는 것은 의문의 여지가 없습니다.

코드베이스에 들어가는 유일한 방법은 사이트 루트에서 시작하여 천천히 그러나 확실하게 링크 된 스크립트를 탐색하는 것입니다. 사용중인 수백 개가 있고 수백 개가 더 많습니다. 사이트의 상당 부분이 Flash에 있다고 가정하면, 특히 오래된 Flash 응용 프로그램에서는 다른 스크립트에 대한 링크가 텍스트 파일 (.AS / ActionScript)이 아닌 바이너리 (.FLA)에 포함될 수 있으므로 훨씬 간단합니다.

그래서 유지 보수성을 위해 코드베이스 전체를 평가하는 방법에 대해 더 나은 제안이있는 사람이 있는지 궁금합니다. 웹 서버 OS의 파일 (내가 액세스 할 수있는 파일)에 대한 액세스 빈도 그래프를 볼 수있는 방법이 있다면 좋을 것입니다. 왜냐하면 파일이 가장 중요하지는 않지만 가장 중요한 파일에 대한 통찰력을 제공 할 수 있기 때문입니다 사용하지 않는 파일을 제거 할 수 있습니다 (일부 파일은 1 년에 한 번만 사용할 수 있으므로).


7
플래시에 대해 충분히 알지 못하지만 코드가 없을 때 컴파일 오류가 발생하면 폴더 이름을 변경하여 참조되는지 확인할 수 있습니다.
Oded

사악한 해결책 : 그것들을 삭제하고 오류 / 버그 보고서를 기다립니다. (그냥 복구 할 수 있는지 확인하십시오!)
Izkata

1
@Nick 다음 단계의 계약의 일부로 평가에 대한 대가를 지불하고 있는지 확인해야합니까? 귀하의 답변은 "도구가 있습니까?"라는 질문을 변경하지는 않지만, 우리 중 일부는 귀하의 상황에 더 적합한 프로세스를 만들 수 있습니다 (예 : 실수를 피하는 등).
jcmeloni

@jcmeloni 아니요, 평가에 대한 비용을 지불하지 않습니다. 그러나 내 경험 과 지난 며칠 동안 내가 얻은 작은 것들에서 그들은 지금 테이블에 다른 사람이 없습니다. 내 스킬 셋은 매우 이례적이므로 견적을 기반으로 경쟁하는 다른 사람이 없기 때문에 훨씬 더 편합니다. 문제의 실제 인용문은 내 고객에서 고객으로, 계약을 다시 보상 할 고객에게 있습니다. 실제로 저는 끝 에서 말을 인용 할 수 있도록 도와 주려고합니다. HTH.
엔지니어

@Oded Rename은 시행 착오 삭제보다 훨씬 쉽습니다! 잘 생각해 그것은 상자에 하나 더 도구입니다.
엔지니어

답변:


32

귀하가 요청한 것은 해당 코드에 대한 작업에 대해 클라이언트 가 다른 클라이언트 (악몽 소유자 코드)에게 적절한 제안서를 작성 하기 위한 입력을 제공하는 것이므로 계속하겠습니다. 사지로이 시점에서 철저한 테스트 나 리팩토링 또는 그 라인을 따라 어떤 것도하지 않을 것이라고 말하십시오. 대략적인 추정치를 얻는 데 시간이 매우 짧은 것 같습니다. 내 대답은 같은 상황에서의 경험을 바탕으로하므로 해석이 잘못되면 뒤에 나오는 모든 것을 무시하십시오.

  • 스파이더 도구를 사용하여 페이지가 무엇이고 인바운드가 무엇인지 파악하십시오. 특정 "감사 목적의 스파이더"도구가 아닌 기본 링크 검사 도구조차도 이와 관련하여 유용합니다.
  • 기본 감사 / 인벤토리 스프레드 시트를 작성하십시오. 이것은 파일 목록과 디렉토리별로 구성된 마지막 수정 시간만큼 간단 할 수 있습니다. 이를 통해 범위를 파악하는 데 도움이되며 _OLD 및 _DELETE와 같은 디렉토리에 도달하면 a) 해당 디렉토리에 없는 항목을 기준으로 평가가 이루어집니다. b) 해당 디렉토리의 존재 및 부패 / 숨겨진 악몽은 어떤 식 으로든 고객의 입찰에서 고려해야 할 더 깊은 문제를 증명합니다 . _OLD 또는 _DELETE에서 가능한 문제를 열거하는 데 오랜 시간을 소비하지 않아도됩니다. 정보는 최종 입찰가에 제공됩니다.
  • 완전히 웹 기반 앱처럼 들리는 것을 검토하고 있다면 표준 로그 분석기 도구도 친구가 될 것입니다. "이것은 액세스 한 스크립트의 상위 10 개에 속합니다"라는 의미 또는 스프레드 시트에 스프레드 시트에 추가 할 수 있습니다. 스크립트가 플래시 파일에 포함되어있어 스파이 더블이 아니더라도 POST 또는 GET을 통해 액세스 할 가능성이 높으며 서버 로그에 표시됩니다. 100 개가 아닌 10 개의 스크립트에 액세스하는 경우 (또는 그 반대로) 유지 관리 작업이 어떻게 진행 될지 잘 알 수 있습니다.

복잡한 사이트에서도 위에서 설명한 것은 하루 또는 하루 반 동안 할 수있는 일입니다. 귀하가 고객 에게 제공 할 답변은 "이것은 엉덩이에 엄청난 고통이 될 것입니다. 그리고 여기에 돼지에게 립스틱을 바르는 몇 가지 이유가 있습니다. 따라서 그에 따라 입찰해야합니다." "또는"합리적인 사람은 유지하지 않고 다시 시작하기 위해 입찰 할 것이므로 그에 따라 입찰해야합니다. "또는"그렇게 나쁘지는 않지만 주어진 기간 동안 일관된 작업 흐름이 될 것입니다. " 요점은 그들이 입찰을 할 것이므로 전체 컨텐츠 및 아키텍처 감사를 수행하기 위해 직접 고용 된 경우와 같이 정확할 필요는 없다는 것입니다.


2
+1 환상적인 답변입니다. +5 버튼은 어디에 있습니까?
엔지니어

1
TL; DR : 필요할 때까지 토끼 구멍으로 몸을 보내지 마십시오. :)
jcmeloni 2016 년

4

" 레거시 코드로 효과적으로 작업하기 "책에있는 패턴을 사용하여 기존 소스 코드를 다시 작성하는 것이 아니라 다시 작성하는 것이 좋습니다 .

이 책은 단위 테스트에서 레거시 코드를 효율적으로 다루는 몇 가지 메커니즘을 자세히 설명하므로 코드를 안전하게 리팩토링 할 수 있습니다. 이 책은 접근 방식의 철학을 설명하는 부분으로 나뉘어져 있으며 "변화를 만드는 데 영원히 걸리는 시간", "시간이 없어서 바꿀 필요가 있습니다"와 같은 특정 문제를 해결하는 여러 장으로 구성되어 있습니다. , "이 수업을 테스트 하네스에 넣을 수 없습니다". 이러한 각 장에는 테스트에서 모범 사례를 실제 문제에 적용하는 방법을 배우는 데 도움이되는 상세하고 입증 된 기술이 있습니다.

이 책을 읽게되면 "우리는 혼자가 아닙니다"라는 사실을 알게되었습니다. 우리 중 대부분 또는 아마도 우리 모두는 관리하기 어려운 복잡한 코드 기반으로 작업하고 있습니다. 이 책에 실린 기술들은 많은 희망을 주었고, 나는 개인적으로 거의 즉시 적용 할 수있었습니다.

Joel Spolsky의 블로그 게시물은 처음부터 시작하는 대신 기존의 작동하는 코드 기반을 유지하는 것이 가장 좋은 이유를 설명하는 훌륭한 작업을 수행합니다. 나는 기사에서 요약을 인용했지만 환상적인 기사를 읽었습니다.

"프로그래머가 항상 코드를 버리고 다시 시작해야하는 미묘한 이유가 있습니다. 그 이유는 이전 코드가 엉망이라고 생각하기 때문입니다. 그리고 여기 흥미로운 관찰이 있습니다. 아마도 잘못된 것입니다. 이전을 생각하는 이유 코드는 엉망입니다. 프로그래밍의 기본적이고 기본적인 법칙 때문입니다.

코드를 작성하는 것보다 코드를 읽는 것이 어렵습니다. " -http : //www.joelonsoftware.com/articles/fog0000000069.html


4
+1. Joel의 말에 따르면, "피의 상태가 좋지 않아야합니다." 문제가 내재 된 것으로 보지 않기 때문입니다. 나는 많은 사람들이 엉뚱한 코드를 작성하고 신경 쓰지 않는 반면, 많은 사람들이 합리적으로 좋은 코드를 작성하지만 "자체 문서화 코드"개념에 따라 살고 있다는 사실을 부분적으로 본다. 개인의 코딩 스타일은 모두 개인 정보 보호를 원하지만 공개 코드베이스와 관련해서는 내일이없는 것처럼 주석을 생성합니다. 아프지 않습니다. 마지막으로, 예산이 좁고 레거시 코드베이스에서 작업해야하는 사람들이 있습니다.
엔지니어

2

일반적인 Java 코드 기반에서는 PMD, FindBugs 또는 Sonar와 같은 도구 사용을 고려한 다음 도구보고 (죽은 코드, 문서화되지 않은 코드, 중복 된 코드 등)를 이해하려고합니다.

보고서를 기반으로 응용 프로그램 / 사이트의 다른 계층 (비즈니스 계층, DB, SQL 등)을 찾으려고합니다.

레이어가 결합되면 (서블릿 내의 HTML, 자바 코드 내의 SQL) 먼저 각 단계를 분리하여 시작합니다. 이러한 각 단계는 분리 된 것으로 간주되어야하며 각 단계의 끝에서 커밋 할 수 있습니다 (분기를 시작한 다음 병합) .


1
감사. 귀하의 답변은 다소 Java에 국한되지만, 계층 적 접근 방식을 보는 것은 흥미 롭습니다. 양파를 벗겨서 말하십시오. 생각할 것.
엔지니어

1

귀하의 설명에 따르면이 코드는 유지 관리 할 수없는 상태에 도달 한 것 같습니다. 이는 가장 좋은 방법은 완전히 다시 작성하는 것입니다. 지저분한 코드베이스를 유지 관리 할 수있는 양질의 도구가 있다면 개발자들은 월급이 훨씬 적습니다. 폴더에서 이전 불필요한 코드를 정리하고 정리하는 것이 가능하지만 수동 작업이므로 무리없이 시간을 보내지 않아도 모든 것을 얻을 수는 없습니다. 나는 여기서 추측하고 있지만 작업 코드 자체는 파일 구조와 엉망입니다. 코드베이스를 활발하게 작동하는 코드로 다듬을 때도 여전히 악몽이 될 것입니다. 무엇이든 업데이트하거나 수정하십시오.

기존 코드를 유지 관리 가능한 상태로 만드는 데 필요한 노력은 다시 작성을 다시 시작하는 노력과 같거나 클 것이라고 강조합니다. 무엇인가를 유지하는 것의 일부는 "창고 뒤에 가져 가서 쏠"시기를 아는 것입니다.


일반적으로 나는 toss-and-rewrite 방식으로 당신과 100 % 일 것입니다. 그러나이 경우 (그리고 적어도 지금은) 몇 주가 걸리는 더 광범위한 점검이 아니라 사이트를 유지하기위한 작업에 대해서만 비용을 지불해야합니다. 또한 지금 당장 원한다고해도 매주 가용성이 명시 적으로 제한되어 있기 때문에 계속 진행하고있는 다른 계약을 계속 유지할 수 없었습니다. 기본 계약은 주당 최소 40 시간.
엔지니어

1
던지기에 동의하지 않고 다시 쓰십시오! 에서 joelonsoftware.com/articles/fog0000000069.html ... "이 프로그래머는 항상 코드를 버리고 다시 시작하려는 미묘한 이유는 이유는 그들이 이전 코드가 엉망이라고 생각한다는 것입니다.입니다. 그리고 여기에 흥미로운 관찰이다 이전 코드가 엉망이라고 생각하는 이유는 기본적인 프로그래밍 법칙 때문이다. 코드를 작성하는 것보다 코드를 읽는 것이 어렵다. " 대신 리팩토링을 강력히 권장합니다. amazon.ca/Working-Effectively-Legacy-Michael-Feathers/dp/…
Kyle Hodgson

1
@KyleHodgson은 때때로 코드가 실제로 엉망이며, 코드를 읽기 전에 코드를 찾기가 엉망인 시점부터 시작하는 시간입니다.
Ryathal

그래, 나는 그 책이 읽을만한 가치가있는 것처럼 보이지만 그렇게 분명하지 않다고 생각합니다. 그것은 코드베이스의 크기 / 복잡성과 작업을 수행 할 수있는 따뜻한 몸에 크게 의존합니다.
엔지니어

1

웹 크롤러는 액세스 가능한 URL을 결정하는 데 도움이 될 수 있습니다. 특히 플래시 나 자바 스크립트에서 링크를 추출 할만큼 똑똑하다면. 웹 페이지 목록이 있으면 웹 페이지를 살펴보고 참조하는 파일을 나열하십시오. 이 프로세스 후에 남은 것은 죽은 코드로 간주해야합니다.


1
나는 당신의 마지막 문장에 동의하지 않습니다. 크롤러는 하나 또는 여러 개의 시작점이있는 직접 그래프로 연결된 페이지 만 찾을 수 있습니다. 그러나 웹 사이트에 대해 말하면 다른 페이지에는 링크하지만 해당 페이지를 가리키는 링크는없는 "랜딩 페이지"라고도합니다. 또한 다른 페이지와 연결이 끊어진 관리 인터페이스의 오래된 부분이있을 수 있습니다. 현재이 유형의 프로젝트가 있습니다.
scriptin

0

참고 : 코드 사용에 대해 묻는 동안 데이터베이스 사용에 악센트를 두었습니다. 대답은 내가 언급 한 모든 시점에서 여전히 두 경우 모두에 적용됩니다.

마지막 단락에서 이미 자신의 질문에 부분적으로 답변했습니다. 응용 프로그램이 실행되는 동안 액세스되는 항목을보십시오.

  1. 데이터베이스프로파일 링하고 프로파일 러에게 하루 동안의 모든 쿼리를 기록하도록 요청할 수 있습니다. 가장 많이 사용되는 데이터베이스 개체에 대한 개요를 제공하지만 사용되지 않은 데이터베이스 개체는 알 수 없습니다. 또한 결과에주의를 기울여야합니다. 예를 들어 테이블은 저장 프로 시저를 통해 독점적으로 사용될 수 있지만 프로파일 러의 쿼리를 보면 테이블이 전혀 사용되지 않는 것처럼 보입니다.

  2. 소스 코드를 검토하고 쿼리를 검색하는 것이 더 유용하며 모든 쿼리를 수집 한 후 빈도 (프로파일 러가 편리한 위치)가 아니라 사용 / 사용하지 않는 관점에서 데이터베이스 사용에 대해 잘 이해할 수 있습니다. 사용 된 테이블. 슬프게도, 수년간 코드베이스에 대해 잘못 작성되거나 유지되지 않는 경우 특히 쿼리가 동적으로 구성되는 경우 ( 매우select 테이블에서 테이블 이름으로 매개 변수를 사용하는 방법을 상상해보십시오 . 어떻게 할 수 있습니까?) 소스 코드를 보면서 매개 변수의 가능한 값을 알 수 있습니까?).

  3. 정적 분석 및 일부 컴파일러는 데드 코드도 공개 할 수 있지만 여전히 원하는 답변을 제공하지는 않습니다.

  4. 데이터 자체 또는 데이터베이스 메타 데이터를 분석하면 흥미로운 정보가 드러날 수 있습니다. 예를 들어, 테이블이 주장에 쉬울 LogonAudit(uniqueidentifier LogonAuditId, datetime LogonEvent, ...)는 10 개 000 2006 2009 년에 하루 기록, 9 월에서 어떤 기록, 18이 포함 된 경우 더 이상 사용되지 않는 일을 , 2009 년 동일은에 대한 사실이 아니다 대부분 읽기 전용으로 들여 쓰기 된 데이터를 포함하는 테이블.

이 네 가지 점이 함께 사용 된 테이블 목록을 제공합니다. 나머지는 사용되거나 사용되지 않습니다. 어설 션을 작성하고 테스트 할 수 있지만 단위 테스트 범위가 충분하지 않으면 쉽지 않습니다. "쉬운"방법도 실패합니다. 예를 들어, products_delme_not_used테이블이있는 경우 테이블이 전혀 사용되지 않는다고 주장하고 코드에서 "products_delme_not_used"를 확인하십시오. 이것은 낙관적입니다. 이전 코드베이스에서 DailyWTF 후보를 찾는 것은 드문 일이 아닙니다.

// Warning: WTF code below. Read with caution, never reuse it, and don't trust
// the comments.

private IEnumerable<Product> GetProducts()
{
    // Get all the products.
    return this.GetEntities<Product>("PRODUCT");
}

private IEnumerable<T> GetEntities<T>(string tableName)
{
    // Everyone knows that SQL is case sensitive.
    tableName = tableName.ToLower();

    if (tableName == "user" || tableName == "product")
    {
        // Those tables were renamed recently in the database. Don't have time
        // to refactor the code to change the names everywhere.
        // TODO: refactor the code and remove this `if` block.
        tableName += "s";
    }

    if (this.IsDelme(tableName))
    {
        // We have some tables which are marked for deletion but are still
        // used, so we adjust their name.
        tableName = this.Delme(tableName);
    }

    return this.DoSelectQuery<T>("select top 200 * from " + tableName);
}

private bool IsDelme(string name)
{
    // Find if the table is among candidates for removal.
    List<string> names = this.Query<string>("select Names from DelmeTables");
    return names.Contains(name);
}

private string Delme(string name)
{
    // Return the new name for a table renamed for deletion.
    return string.Join("_", new [] { name, "delme", "not", "used" });
}

이 코드가 실제로 products_delme_not_used테이블을 사용한다는 것을 알 수 있습니까 ?

내가 만약 너라면 나는:

  1. 모든 데이터베이스 개체를 그대로 유지
  2. 전체 응용 프로그램을 리팩터링합니다 (가치가있는 경우).
  3. 애플리케이션 및 특히 데이터베이스 사용량을 문서화 (리팩토링하는 동안)하십시오.

마지막 두 단계를 마치면 더 이상 사용되지 않는 테이블의 이름을 파악하는 데 도움이되는 데이터베이스 사용법에 대해 더 잘 이해하게되며 다소 안전하게 제거 할 수 있습니다.


0

견적을 작성하기 위해 충분한 정보를 얻어야하므로 그 노력에 집중하겠습니다.

이 사이트와 관련된 사용 사례 수를 결정하려고합니다. 일반적으로 사이트의 규모와 복잡성, 사이트 / 응용 프로그램을 다시 만들거나 유지 관리하는 데 걸리는 시간에 대한 아이디어를 제공합니다.

예, 때로는 코드가 더 이상 사용되지 않고 응용 프로그램이 실제보다 조금 더 크게 보일 수는 있지만 사실이 숫자가 최대 20 % 이상 영향을 줄 것이라고 생각하지 않습니다. 그래서 나는 그 부분에 대해 걱정하지 않을 것입니다.

소스 코드, 웹 페이지 및 데이터베이스 테이블을 보면이를 쉽게 찾을 수 있습니다.

또한 자신을 보호하기 위해 사전 결정된 요금으로이 프로젝트에 사용할 월별 시간 수를 제한하는 것이 좋습니다.

사용되고 있거나 사용되지 않는 것을 발견하는 한 쉬운 방법은 없습니다. 코드 분석 도구가 도움이 될 수 있지만 이러한 혼합 된 악을 다루기 때문에 도움이 될 수있는 도구가 하나도 없다고 생각합니다. 각 특정 영역에 대해 도움이 될 수있는 코드 분석 도구를 찾을 수 있습니다.

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