길지만 간단한 코드를 클래스 나 함수로 래핑하는 대신 복사하여 붙여 넣을 수 있습니까?


29

인터넷에 연결하고 다음과 같은 연결 결과를 표시하는 코드 세그먼트가 있다고 가정하십시오.

HttpRequest* httpRequest=new HttpRequest();
httpRequest->setUrl("(some domain .com)");
httpRequest->setRequestType(HttpRequest::Type::POST);
httpRequest->setRequestData("(something like name=?&age=30&...)");
httpRequest->setResponseCallback([=](HttpClient* client, HttpResponse* response){
    string responseString=response->getResponseDataString();
        if(response->getErrorCode()!=200){
            if(response->getErrorCode()==404){
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setFontColor(255,255,255);
                alert->setPosition(Screen.MIDDLE);
                alert->show("Connection Error","Not Found");
            }else if((some other different cases)){
                (some other alert)
            }else
                Alert* alert=new Alert();
                alert->setFontSize(30);
                alert->setPosition(Screen.MIDDLE);
                alert->setFontColor(255,255,255);
                alert->show("Connection Error","unknown error");
            }
        }else{
            (other handle methods depend on different URL)
        }
}

코드는 길고 일반적으로 사용되지만 위의 코드에는 사용자 정의 함수 및 클래스 (HttpRequest 및 Alert는 기본적으로 프레임 워크에서 제공)와 같은 추가 항목이 필요하지 않으며 코드 세그먼트는 길지만 코드 세그먼트는 길지만 간단하고 복잡하지 않습니다 (URL, 글꼴 크기와 같은 설정 묶음이 있기 때문에 길고 코드 세그먼트는 클래스마다 약간의 차이가 있습니다 (예 : URL, 요청 데이터, 오류 코드 처리 사례, 일반 처리) 사례 ...)

내 질문은 코드의 종속성을 줄이기 위해 함수에 래핑하는 대신 길지만 간단한 코드를 복사하여 붙여 넣는 것이 허용됩니까?


89
할당 한 객체를 해제하지 않는 등 해당 코드에 버그가 있다고 상상해보십시오. (프레임 워크에서 Alert객체를 해제합니까?) 이제 버그를 수정하려면이 코드의 복사 된 모든 인스턴스를 찾아야한다고 상상해보십시오. 이제 당신이 그것을해야하는 사람이 아니라 당신을 아는 미친 도끼 살인자라고 생각하십시오.
Sebastian Redl

8
한 곳에서 네트워킹과 오류 표시를 혼합하는 BTW는 이미 큰 IMHO입니다.
sleske

11
아뇨. 완전히 받아 들일 수 없습니다. 내 프로젝트에 있다면 더 이상 내 프로젝트에 있지 않으며 교육 프로그램 또는 PIP에 있습니다.
nhgrif

10
"화면 중앙에있는이 경고 상자는 절대 공포입니다. 고양이 지프를보고 팝업이 표시 될 때마다 화면이 보이지 않습니다. 오른쪽 상단으로 이동하십시오." " 3 주 후 "도대체 어떻게 했습니까?! 팝업이 오른쪽 상단의 X를 덮고 있기 때문에 더 이상 고양이 지프를 닫을 수 없습니다."
MonkeyZeus

11
나는 여기의 모든 사람들이 이것이 나쁜 생각이라고 생각하는 것 같습니다. 그러나 질문을 돌리기 위해 왜이 코드를 별도의 클래스 나 함수에 넣지 않겠습니까?
Karl Gjertsen

답변:


87

변경 비용을 고려해야합니다. 연결 방법을 변경하려면 어떻게해야합니까? 얼마나 쉬울까요? 중복 된 코드가 많은 경우 변경해야하는 모든 위치를 찾는 데 시간이 많이 걸리고 오류가 발생하기 쉽습니다.

또한 명확성을 고려해야합니다. 대부분의 경우 30 줄의 코드를 보더라도 "connectToInternet"함수를 한 번만 호출하는 것만 큼 이해하기 쉽지 않을 것입니다. 새로운 기능을 추가해야 할 때 코드를 이해하려고하는데 시간이 얼마나 많이 걸리나요?

복제가 문제가되지 않는 드문 경우가 있습니다. 예를 들어 실험을하고 있는데 하루가 끝날 때 코드가 삭제되는 경우가 있습니다. 그러나 일반적 으로 복제 비용은 코드를 별도의 기능으로 끌어낼 필요가 없기 때문에 시간이 절약됩니다 .

참조 https://softwareengineering.stackexchange.com/a/103235/63172


19
...이 30 라인이 이전에 보았던 다른 라인과 실제로 같은지 또는 누군가 어떤 이유로 든 자신의 사본에서 다른 포트 또는 IP 주소로 전환했는지 알고있는 사람. "로 시작하는 30 줄 HttpRequest이 모두 같다 "는 암시적인 가정은 오류를 범하기 쉽다.
null

@null 최고점. 한 번 데이터베이스 연결 훅업이 복사되어 붙여진 코드를 작업했지만 일부는 설정에 미묘한 차이가있었습니다. 이러한 고의적 변경, 또는 무작위 차이가 중요이라면 나는 몰랐다
user949300

54

아니.

실제로 "간단한"코드조차도 더 작은 부분으로 나눠야합니다. 적어도 두 사람

하나는 연결하고 정상적인 200 응답을 처리합니다. 예를 들어, 경우에 따라 POST에서 PUT으로 변경하면 어떻게됩니까? 이러한 연결을 수백만 개 작성하고 멀티 스레딩 또는 연결 풀링이 필요한 경우 어떻게합니까? 메소드에 대한 인수와 함께 한 곳에서 코드를 작성하면 훨씬 쉽게 만들 수 있습니다.

마찬가지로, 다른 오류를 처리합니다. 예를 들어 경고의 색상 또는 글꼴 크기를 변경하는 경우 또는 간헐적 인 연결에 문제가 있고 오류를 기록하려고합니다.



SRP를 인용 할 수도 있습니다. 한 가지 목적을 가진 코드 블록을 사용하면 이해하고 유지하기가 훨씬 쉬워집니다.
Roland Tepp

이것은 DRY와 SRP가 실제로 정렬되는 경우입니다. 때로는 그렇지 않습니다.
user949300

18

복사하여 붙여 넣을 수 있습니까?

아니.

나에게 결정적인 주장은 이것이다.

... 일반적으로 사용됩니다 ...

이상의 장소 에서 코드를 사용하는 경우 코드가 변경 될 때 이상의 위치 에서 코드 를 변경 해야합니다. 그렇지 않으면 불일치가 발생하기 시작합니다.

그것은 간단하고 복잡하지 않습니다 ...

그리고 함수로 리팩토링하기가 더 쉬워야합니다.

... URL, 글꼴 크기와 같은 설정 번들이 있습니다 ...

그리고 사용자는 무엇을 하는가 을 바꾸고 싶어 합니까? 글꼴, 글꼴 크기, 색상 등

지금; 동일한 색상 / 글꼴 / 크기를 다시 얻기 위해 동일한 코드를 몇 곳에서 변경해야합니까? (권장 답변 : 단 하나 ).

... 코드 세그먼트는 클래스마다 약간의 변형이 있습니다 (예 : URL, 요청 데이터, 오류 코드 핸들 케이스, 일반 핸들 케이스 ...)

변형 => 기능 매개 변수.


"그리고 사용자들은 무엇을 바꾸고 싶어 하는가? 글꼴, 글꼴 크기, 색상 등"이 다루어지고있다. 당신은 정말로 수십 곳에서 그것을 바꾸고 싶습니까?
Dan

8

이것은 실제로 복사하여 붙여 넣기와 관련이 없습니다. 다른 곳에서 코드를 가지고가는 경우에, 두 번째에서 당신은 코드를 그것의 가지고 당신의 코드와 당신 이 복사하거나 변화를하지 않는 자신에 의해 완전하게 작성 그래서 여부, 책임.

경고에서 일부 디자인 결정을 내립니다. 모든 경보에 대해 유사한 설계 결정을 내려야합니다. 따라서 "ShowAlertInAStyleSuitableForMyApplication"어딘가에 있거나 약간 더 짧은 메소드가 있어야하며,이 메소드를 호출해야합니다.

유사한 오류 처리와 함께 많은 http 요청이 있습니다. 오류 처리를 반복해서 반복하지 말고 일반적인 오류 처리를 추출하십시오. 특히 오류 처리가 조금 더 정교 해지면 (시간 초과 오류, 401 등은 어떻습니까).


6

일부 상황에서는 복제가 가능합니다. 그러나 이것에는 없습니다. 그 방법은 너무 복잡합니다. 방법을 "인수 분해"하는 것보다 복제가 더 쉬운 경우에는 하한이 있습니다.

예를 들면 다음과 같습니다.

def add(a, b)
    return a + b
end

바보입니다, 그냥 a + b를하십시오.

그러나 조금 더 복잡해지면 보통 줄을 서게됩니다.

foo.a + foo.b

되어야한다

foo.total
def foo
    ...
    def total
        return self.a + self.b
    end
end

귀하의 경우에는 네 가지 "방법"이 있습니다. 아마도 다른 수업에서. 하나는 요청을하고, 하나는 응답을 받고, 하나는 오류를 표시하며, 응답이 응답을 처리하기 위해 리턴 된 후 호출되는 일종의 콜백입니다. 나는 개인적으로 그 위에 "래퍼"를 추가하고 통화를 더 쉽게 할 것입니다.

결국 웹 요청을하려면 다음과 같은 호출을 원합니다.

Web.Post(URI, Params, ResponseHandler);

그 줄은 코드 전체에 걸쳐있을 것입니다. 그런 다음 "물건을 얻는 방법"을 변경해야 할 때 훨씬 적은 노력으로 빠르게 할 수있었습니다.

이것은 또한 코드 DRY를 유지하고 SRP를 도와줍니다 .


0

모든 크기 / 복잡성 프로젝트에서 다음 목적으로 필요할 때 코드를 찾을 수 있기를 원합니다.

  1. 고장 났을 때 고치세요
  2. 기능 변경
  3. 재사용하십시오.

진행중인 프로젝트에 참여하거나 몇 년 동안 프로젝트 작업을 계속하고 "인터넷에 연결하여 연결 결과 표시"라는 새로운 요청이 위치를 찾기 때문에 위치를 찾기가 쉬운 경우에 좋지 않습니까? httprequest에 대한 코드 전체에서 검색을 수행하는 대신 좋은 디자인? 어쨌든 구글에서 더 쉽게 찾을 수 있습니다.

걱정하지 마십시오. 저는 새로운 사람이며이 코드 블록을 리팩터링 할 것입니다. 왜냐하면이 단서가없는 팀을 끔찍한 코드베이스와 함께하게되어 너무나 화나게 되었기 때문입니다. 당신은 그것을 복사하여 붙여 넣을 것입니다. 적어도 상사가 내 등을 막을 것이다. 그런 다음 프로젝트가 실제로 재난으로 식별되면, 우리 중 누구도 이해하지 못하는 최신의 가장 큰 프레임 워크에 버전을 복사하여 붙여 넣어 프로젝트를 다시 작성하는 것이 좋습니다.


0

적어도 제 생각에는 클래스 및 / 또는 기능이 더 좋습니다. 저장 공간이 적은 장치 (IoT, 구형 전화 등)의 웹 응용 프로그램 또는 응용 프로그램을 처리하는 경우 한 번만 파일 크기가 작아 져 매우 큰 이득이됩니다.

그리고 가장 좋은 점은 새로운 프로토콜 등으로 인해 변경해야 할 사항이 있으면 함수의 내용을 변경 하고이 기능을 다른 파일에 넣을 수도있는 어딘가에 여러 번 넣지 않는 것입니다. 찾아 변경하십시오.

전체 SQL 인터프리터를 작성하여 PHP 에서 MySQL에서 MySQLi 로 더 잘 전환 할 수 있습니다. 통역을 변경해야하고 모든 것이 효과가 있기 때문에 약간의 극단적 인 예입니다.


-1

코드를 복제해야하는지 또는 두 번 호출되는 함수로 이동해야하는지 결정하려면 더 가능성이 높은 코드를 결정하십시오.

  1. 코드의 두 가지 용도를 같은 방식으로 변경해야합니다.

  2. 코드를 다르게 사용하도록 최소한 한 번의 코드 사용을 변경해야합니다.

첫 번째 경우 두 기능을 모두 처리하는 기능이 하나있는 것이 좋습니다. 후자의 경우 두 사용법에 대해 별도의 코드를 갖는 것이 좋습니다.

한 번 사용되는 코드를 인라인으로 작성해야하는지 아니면 다른 함수로 가져와야하는지 결정할 때 함수의 필수 동작을 어떻게 완전히 설명하는지 알아보십시오. 함수의 필수 동작에 대한 완전하고 정확한 설명이 코드 자체보다 길거나 길면 코드를 별도의 함수로 이동하면 이해하기가 쉽지 않을 수 있습니다. 두 번째 발신자가 동일한 기능을 사용해야 할 가능성이 높고 향후 기능 변경이 두 발신자 모두에게 영향을 미칠 필요가있는 경우에도 여전히 가치가 있지만 그러한 고려가 없으면 가독성은 분할하는 것이 좋습니다. 코드와 필요한 동작에 대한 설명이 거의 같은 수준까지.

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