팀에서 빌더 패턴 사용을 어떻게 홍보 할 수 있습니까?


22

우리의 코드베이스는 나 자신과 마찬가지로 오래되고 새로운 프로그래머 이며 균일 성을 위해 수행 된 방식으로 신속하게 학습합니다 . 우리는 어딘가에서 시작해야한다고 생각하면서 다음과 같이 데이터 홀더 클래스를 리팩터링했습니다.

  • 세터 메소드를 제거하고 모든 필드를 작성했습니다 final( final공식적으로 "양호합니다"). 세터는 생성자에서만 사용되었으므로 부작용이 없었습니다.
  • 빌더 클래스 소개

생성자 (처음에 리팩토링을 촉구 한 것)가 약 3 줄의 코드에 걸쳐 있기 때문에 Builder 클래스가 필요했습니다. 그것은이 많은 매개 변수를.

운 좋게도 내 팀원은 다른 모듈을 연구하고 있었고 세터가 필요했습니다. 필요한 값이 흐름의 다른 지점에서 가능해 졌기 때문입니다. 따라서 코드는 다음과 같습니다.

public void foo(Bar bar){
    //do stuff
    bar.setA(stuff);
    //do more stuff
    bar.setB(moreStuff);
}

나는 setter를 제거하면 필드가 불변 상태로 남아 있기 때문에 (이전에 불변성에 대해 열렬한 소리를 들었음) 빌더가 객체 생성을 트랜잭션으로 허용하기 때문에 빌더를 대신 사용해야한다고 주장했습니다. 다음 의사 코드를 스케치했습니다.

public void foo(Bar bar){
    try{
        bar.setA(a);
        //enter exception-throwing stuff
        bar.setB(b);
    }catch(){}
}

해당 예외가 발생하면 bar데이터가 손상되어 빌더로 피할 수 있습니다.

public Bar foo(){
        Builder builder=new Builder();
    try{
        builder.setA(a);
        //dangerous stuff;
        builder.setB(b);
        //more dangerous stuff
        builder.setC(c);
        return builder.build();
    }catch(){}
    return null;
}

팀원들은 문제의 예외가 절대 발생하지 않을 것이라고 회고했습니다. 이는 특정 코드 영역에 대해 충분히 공평하지만 나무의 숲이 빠져 있다고 생각합니다.

타협은 기존 솔루션으로 되돌아가는 것입니다. 즉 매개 변수가없는 생성자를 사용하고 필요에 따라 세터로 모든 것을 설정합니다. 근거는이 솔루션이 KISS 원칙을 따른다는 것입니다.

나는이 회사를 처음 접했고 (6 개월 미만)이 회사를 잃어 버렸다는 것을 완전히 알고 있습니다. 내가 가진 질문은 다음과 같습니다.

  • "구식"대신 빌더를 사용하는 또 다른 주장이 있습니까?
  • 내가 제안한 변화가 정말 가치가 있습니까?

하지만 정말,

  • 새로운 것을 시도 할 때 그러한 주장을 더 잘 표현할 수있는 팁이 있습니까?

6
빌더는 어떻게 든 값을 설정해야합니다. 따라서 기본적인 문제는 해결되지 않습니다.
Amy Blankenship

3
전화 하기 전에 (더 많은 / 위험한 / 예외 던지는) 물건을 옮길 수없는 이유는 무엇입니까 setA?
yatima2975

2
생성자 매개 변수의 3 라인? 그렇게 나쁘지 않습니다.
pjc50

7
모든 소프트웨어 디자인에서 복잡성과 디커플링 간에는 항상 상충 관계가 있습니다. 나는 여기서 빌더가 좋은 솔루션이라는 것을 개인적으로 동의한다고 생각하지만, 동료는 KISS의 근거를 망설이는 것이 맞습니다. 놀랍도록 지나치게 복잡하게 된 소프트웨어를 유지하고 있으며 그 이유 중 일부는 모든 신입 사원이 사기를 일으키고 "이것은 어리석은 일입니다.이 새로운 일을 저의 방식으로 할 것입니다"라고 말합니다. 백그라운드 작업 및 데이터베이스 쿼리를위한 8 가지 방법 모든 것이 적당하며 이와 같은 경우에는 명확한 정답이 없습니다.
Brandon

3
KISS는 퍼지 개념이며 수정 가능한 객체는 개발자가 과소 평가하는 복잡성의 원천이며 멀티 스레딩, 디버그 및 예외 처리를 불변의 것보다 훨씬 어렵게 만듭니다. 객체가 유효하거나 구성에서 예외가 생성됩니다 (해당 예외를 포착하기에 더 좋은 곳은 어디입니까?).
Alessandro Teruzzi

답변:


46

우리는 어딘가에서 시작해야한다고 생각하면서 데이터 홀더 클래스를 리팩토링하기 위해 스스로 취했습니다.

이것이 잘못 된 부분입니다. 코드베이스를 크게 변경하여 예상과 크게 달라졌습니다. 당신은 동료들을 놀라게했습니다. 서프라이즈는 파티와 관련된 경우에만 유효합니다. 최소한의 놀람의 원칙은 황금입니다 (파티가 포함되어 있어도 깨끗한 속옷을 입는다는 것을 알고 있습니다!)

이제이 변경이 가치가 있다고 생각되면 변경을 보여주는 의사 코드를 스케치하여 동료 (또는 최소한 건축가와 가장 가까운 역할을 가진 사람)에게 제시하고 어떤 일을하기 전에 그들이 생각한 것을 보는 것이 훨씬 더 좋을 것입니다. 그대로, 당신은 악성으로 갔고, 모든 코드베이스가 당신이 적합하다고 생각하는 것처럼 당신의 것으로 생각했다고 생각했습니다. 팀 플레이어가 아닌 팀의 플레이어!

나는 당신에게 약간 가혹할지도 모르지만, 나는 반대 위치에 있었다 : 일부 코드를 확인하고 "WTF가 여기에 있었습니까?!"라고 생각하고, 새로운 사람 (거의 항상 새로운 사람)을 찾기 위해서만 변경하기로 결정했습니다. 그가 "올바른 길"이되어야한다고 생각하는 것에 근거한 많은 것들. SCM 히스토리가있는 나사도 또 다른 중요한 문제입니다.


7
"서프라이즈는 파티와 관련된 경우에만 좋습니다." 실제로 모든 사람에게 해당되는 것은 아닙니다. 나는 소위 어떤 친구 , 특히 파티를 놀라게하는 친구에게 말을 걸지 않을 입니다. 사람들 과 함께 . 어.
Darkhogg

3
모든 리팩토링과 디자인 패턴 또는 "여기에서 접근 자와 뮤 테이터 또는 빌더 패턴을 사용합니까?" 팀의 승인을 받아야하는 경우 개발자가 올바른 작업을 수행 할 수있는 권한을 어떻게 느끼게 되나요? 모든 것이위원회에 의해 설계되어야한다면 어떻게 미래 지향적 인 변화를 만들 것입니까? 나는 다른 사람들이 일관성이 있기 때문에 다른 사람들이 변경하기를 두려워하는 무의미한 코드를 유지해야하기 전에 OP의 신발을 신었습니다 . 일관성은 우수하지만 개선의 대가는 아닙니다.
Brandon

11
@Brandon 아니오, 그러나 그들에게 영향을 미칠 모든 광범위한 변화가 있어야합니다. 버그를 수정해야한다면 코드의 또 다른 비트가 될 것입니다. 다른 사람에게 영향을 미치는 결정을 내린다면, 적어도 당신이하는 일을 그들에게 알리는 것이 예의입니다. 팀의 동의를 얻어 의미없는 코드를 변경하면 변경 사항이 새로운 일관성이됩니다. 동료들과 대화하면됩니다. 아무것도 나쁜와 함께 동료의 응답을 듣고 "나는 엉터리 접근 패턴 우리 모두 증오를 변경하는거야"말에 대해있다 "그래, 그것에 대한 시간 누군가가 그 처리"
gbjbaanb

13
@Brandon은 "지옥으로 향하는 길은 좋은 의도로 포장되어 있습니다"라고 말합니다. 일관성은 좋지 않다 , 그것은 필요하다 ! 환경 설정, 현재 기술, 트렌드 등이 당시 가장 좋은 것을 지시했기 때문에 각각 20 개의 응용 프로그램을 총체적으로 관리하는 개발자 팀을 관리하려고한다고 상상해보십시오. 각각 다른 스타일 및 / 또는 아키텍처로 작성되었습니다. 팀원들에게 변화가 필요하다는 것에 동의하게 만드는 것은 새로운 문제가 오래 지속되는 문제를 해결했기 때문에 받아 들여지고, 자신 이 가장 잘 생각한 것에 대해 무심한 태도로 해고당하는 것의 차이가 될 수 있습니다 .
DrewJordan

3
@Brandon-당신이 "모두가 동의하는 것"을 악의적으로 고치려고한다면, 아마도 다른 캠프를 가진 다른 것을 선택하는 것보다는 "모두가 동의하는 것"을 선택함으로써 더 큰 성공을 거둘 것입니다. 불변성과 같은 주제. 우수한 디자인 / 아키텍처는 실질적으로 보상없이 불변성을 높은 비용으로 만듭니다. 따라서 팀이 세터를 사용하여 문제가 발생하지 않는 한 전혀 문제를 해결하지 않았습니다. OTOH, 이것이 빈번한 버그의 원인이라면 파급 효과가 팀 결정을 정당화하는 것처럼 보입니다.
Dunk

21

운 좋게도 내 팀원은 다른 모듈을 연구하고 있었고 세터가 필요했습니다. 필요한 값이 흐름의 다른 지점에서 가능해 졌기 때문입니다.

설명했듯이 코드 설정자를 필요로 하는 것을 보지 못했습니다 . 유스 케이스에 대해 충분히 알지 못하지만 객체를 인스턴스화하기 전에 모든 매개 변수가 알려질 때까지 기다리지 않는 이유는 무엇입니까?

대안으로 상황에 setter가 필요한 경우 : 오브젝트가 준비된 후 필드를 수정하려고하면 setter에 어설 션 오류 (일명 프로그래머 오류)가 발생하도록 코드를 고정하는 방법을 제공하십시오.

나는 setter를 제거하고 final을 사용 하는 것이 불변성을 강화하는 것뿐만 아니라 그것을 수행하는 "적절한"방법 이라고 생각 하지만 실제로 당신이 시간을 보내야하는 것입니까?

일반적인 팁

Old = bad, new = good, my way, your way ... 이런 종류의 토론은 건설적이지 않습니다.

현재 객체 사용 방식은 몇 가지 암시 적 규칙을 따릅니다. 이것은 코드의 작성되지 않은 사양의 일부이며 팀은 코드의 다른 부분이 코드를 잘못 사용하는 위험이 크지 않다고 생각할 수 있습니다. 여기서 수행하려는 작업은 빌더 및 컴파일 타임 검사를 통해 규칙을보다 명확하게 만드는 것입니다.

어떤 식 으로든 코드 리팩토링은 깨진 창 이론과 관련이 있습니다. 문제가 발생했을 때 문제를 해결하거나 나중에 "품질 개선"회의에 대한 메모를 작성하여 코드가 항상 작업하기에 편한 것처럼 느껴지더라도, 안전하고 깨끗합니다. 당신과 당신의 팀은 "충분히 좋은"것에 대해 같은 생각을하지 않습니다. 성실하게 코드를 작성하고 개선 할 수있는 기회로 보는 것은 기존 팀과 다르게 보일 수 있습니다.

그건 그렇고, 당신의 팀이 반드시 관성, 나쁜 습관, 교육 부족으로 고통받는 것으로 가정해서는 안됩니다 ... ... 당신이 할 수있는 최악의 일은 그들을 아는 모든 사람 의 이미지를 투영하는 것입니다 코딩하는 법. 예를 들어, 불변성은 새로운 것이 아니며 동료가 그것에 대해 읽었을 수도 있지만 블로그 에서이 주제가 인기를 얻고 있기 때문에 코드를 변경하는 데 시간을 소비하도록 설득하기에는 충분하지 않습니다.

결국 기존 코드베이스를 개선 할 수있는 끝없는 방법이 있지만 시간과 비용이 든다. 나는 당신의 코드를보고, 그것을 "오래된"것으로 부르고 nitpick에 대해 찾을 수 있습니다. 예를 들어, 공식적인 사양이없고, 주장이 충분하지 않거나, 주석이나 테스트가 충분하지 않거나, 코드 적용 범위가 충분하지 않거나, 최적화되지 않은 알고리즘, 너무 많은 메모리 사용량이 있으며, 각 경우에 "최상의"가능한 디자인 패턴을 사용하지 않는 경우 등이 있습니다. ad nauseam . 그러나 내가 제기 할 대부분의 포인트에 대해 생각할 것입니다. 제 코드가 작동하면 더 많은 시간을 할애 할 필요가 없습니다.

어쩌면 팀은 당신이 제안한 것이 수익 감소의 시점을 넘어서고 있다고 생각할 수도 있습니다. 예제의 종류로 인해 실제 버그 인스턴스를 찾았더라도 (단, 예외를 제외하고) 버그를 한 번만 수정하면 코드를 리팩토링하고 싶지 않을 것입니다.

질문에 관한 것입니다 그래서 어떻게 당신의 시간과 에너지를 소비하는, 그들이 주어진 제한 ? 소프트웨어에는 지속적인 변화가 있지만 일반적으로 좋은 주장을 할 수있을 때까지 아이디어는 음의 점수로 시작합니다. 당신이 그 혜택에 대해 옳다고해도 "그것이 좋은데, 언젠가 ... "바구니 에서 끝날 것이기 때문에 그 자체로는 충분한 주장이 아닙니다 .

당신이 당신의 주장을 제시 할 때, 당신은 "위생"체크를해야합니다 : 당신은 아이디어 나 당신 자신을 팔려고합니까? 다른 사람이 이것을 팀에 제시하면 어떻게됩니까? 그들의 추론에 결함이 있습니까? 일반적인 모범 사례를 적용하려고합니까, 아니면 코드의 특성을 고려 했습니까?

그런 다음 팀의 과거 "실수"를 수정하려고하는 것처럼 표시되지 않아야합니다. 그것은 당신이 당신의 아이디어는 아니지만 합리적으로 피드백을받을 수 있음을 보여주는 데 도움이됩니다. 더 많이할수록 제안을 따를 기회가 더 많아집니다.


너가 확실히 맞아. 작은 반대 : 그것은 "오래된 방법"대 "나의 새로운, 아주 멋진 새로운 방법"이 아닙니다. 나는 말도 안되는 말을 잘 알고 있습니다. 내 문제는 회사의 모든 사람이 끔찍한 소프트웨어 관행을 계속 사용함으로써 개발자로 정체 될 수 있다는 것입니다. 따라서 내가 틀렸어도 변화를 소개하려고합니다. (작업은 관련 클래스를 리팩토링하라는 요청에 의해 트리거되었습니다)
rath

@rath 새로운 코드베이스가 개발되고 있지 않습니까?
biziclop

@biziclop 기존 코드베이스에 새로운 모듈이 연결되었습니다. 나는 최근에 일했다. 행복한 날들.
rath

5
@rath 아마도 당신은 당신이 당신의 자신의 개발을 발전시킬 수있는 자신의 시간에 작업 할 수있는 개인 프로젝트가 필요하십니까? "Builder"패턴 인수에 대해서도 확신하지 않습니다. 게터 / 세터는 제공 한 정보를 바탕으로 완벽하게 괜찮은 솔루션 인 것 같습니다. 고용주와 팀에게 책임이 있음을 기억하십시오. 우선 순위는 귀하가하는 모든 업무가 귀하가 책임있는 업무에 이익이되도록하는 것입니다.
벤 Cottrell

@rath 글쎄, 당신이 "오래된 / 새로운"코드에 있지 않더라도, 중요한 것은 수신 측이 어떻게 인식하는지, 특히 그들이 당신보다 더 많은 결정력을 가지고 있다면 어떻게 인식되는지입니다. 개발하는 제품이 아니라 자신의 관심사에 변화를 도입하려는 것처럼 보입니다. 회사의 모든 사람들이 연습이 끔찍한 것을 발견하면 결국에는 변할 것이지만 이것이 우선 순위처럼 보이지는 않습니다.
coredump

17

팀에서 빌더 패턴 사용을 어떻게 홍보 할 수 있습니까?

당신은하지 않습니다.

생성자에 3 줄의 매개 변수가 있으면 너무 크고 너무 복잡합니다. 어떤 디자인 패턴으로도 해결할 수 없습니다.

다른 시간에 데이터를 사용할 수있는 클래스가있는 경우 두 개의 다른 객체이거나 소비자가 구성 요소를 집계 한 다음 객체 구성해야합니다. 그렇게하기 위해 건축업자가 필요하지 않습니다.


Strings 및 기타 기본 요소의 큰 데이터 홀더입니다 . 어디에도 논리가 없으며 nulls 등을 확인조차하지 않습니다 . 따라서 복잡성 자체가 아니라 단순한 크기입니다. 나는 builder.addA(a).addB(b); /*...*/ return builder.addC(c).build();눈에서 훨씬 더 쉬운 일을 할 것이라고 생각했습니다 .
rath

8
@rath : Strings 및 기타 기본 요소의 큰 데이터 홀더입니다. => 그러면 다른 문제가 생길 수 있습니다. 우연히 전자 메일 필드에 사람의 우편 주소가 할당되면 아무도 신경 쓰지 않기를 바랍니다.
Matthieu M.

@MatthieuM. 한 번에 한 가지 문제가 있다고 가정 :)
rath

@rath-빌더 유효성 검사 패턴을 기존 코드에 충돌시키는 방법을 알아내는 것보다 좋은 유효성 검사 체계를 통합하는 것이 훨씬 유용하고 쉽게 받아 들인 것처럼 보입니다. 다른 곳에서는 자신을 개선하고 싶다고 말했습니다. 최소한의 노력과 결과로 최대의 이익을 얻는 방법을 배우는 것은 분명히 개발해야 할 특성입니다.
Dunk

1
나는 그보다 더 많은 매개 변수를 가진 많은 생성자를 가지고 있습니다. IoC 패턴에 필요합니다. 이 답변의 나쁜 일반화.
djechlin

16

당신은 다른 사람들과 잘 일하는 것보다 옳은 일에 집중하는 것 같습니다. 더 나쁜 것은, 당신이하는 일이 힘의 투쟁이지만, 당신이 경험과 권위에 도전하는 사람들에게 어떤 일이 느껴질 지 생각하지 못하는 것입니다.

그 반대로.

다른 사람들과 함께 일하는 데 집중하십시오. 당신의 생각을 제안과 아이디어로 구성하십시오. 그들이 당신의 생각을하게하기 위해 질문을하기 전에 THEIR 아이디어를 통해 대화하도록하십시오. 직접적인 대립을 피하고 그룹을 변화시키기 위해 오르막 전투를 싸우는 것보다 그룹의 길 (현재로서는)을하는 것이 더 생산적이라는 사실을 외면적으로 기꺼이 받아들이십시오. (물건을 다시 가져 오십시오.) 기쁨을 느끼십시오.

이를 일관성있게 수행하면 갈등이 줄어들고 다른 사람들이 더 많은 아이디어를 채택하게됩니다. 우리는 모두 완벽한 논리적 주장이 다른 사람들을 놀라게하고 하루를 이길 것이라는 환상으로 고통 받고 있습니다. 그리고 그것이 그렇게 작동하지 않으면, 우리는 그렇게 생각 합니다 .

그러나 그것은 현실과 직접적인 충돌이다. 첫 번째 논리적 인 점이 나오기 전에 대부분의 주장은 없어집니다. 이론적으로 논리적 인 사람들 중에서도 심리학은 이성보다 우선합니다. 사람들을 설득시키는 것은 완벽한 논리를 가지지 않고 제대로 들리는 것에 대한 심리적 장벽을 극복하는 것입니다.


2
Frame your thoughts as suggestions and ideas. Get THEM to talk through THEIR ideas before asking questions to make them think about yours그럼에도 불구하고 +1
rath

2
@rath 다른 사람들이 귀하의 책을 읽지 않을 수도 있음을 명심하십시오. 토론중인 사람이 자신의 목표에 반하는 생산적인 대립으로 간주 될 수 있습니다.
Iker

2
@rath : 옳고 그름은 없습니다. 그냥 거래하십시오. 그리고 종종 트레이드 오프에는 코드 이상의 것이 포함됩니다.
Marjan Venema

1
@ 덩크 존재하는 모든 것은 트레이드 오프입니다. 트레이드 오프가 명백하고 명백하게 한쪽에있을 때 우리는 그것들을 옳고 그름이라고 부릅니다. 그러나 처음부터 타협점에 초점을 맞추면 그 음영이 모호한 시점을 인식하는 것이 더 쉽습니다.
btilly

2
내가 알지 못하는 단일 프로그래밍 "모범 사례"는 없습니다. 때로는 이러한 예외를 찾기가 어렵지만 항상 존재합니다.
btilly

11

"구식"대신 빌더를 사용하는 또 다른 주장이 있습니까?

"새로운 망치가 있으면 모든 것이 못처럼 보일 것입니다." -이것이 내가 당신의 질문을 읽을 때 생각한 것입니다.

내가 동료라면 "생성자에서 전체 객체를 초기화하지 않는 이유는 무엇입니까?" 그것이 결국 기능입니다. 빌더 (또는 다른 디자인) 패턴을 사용하는 이유는 무엇입니까?

내가 제안한 변화가 정말 가치가 있습니까?

작은 코드 스 니펫에서 말하기는 어렵습니다. 어쩌면 그것은 당신입니다-당신과 당신의 동료는 그것을 평가해야합니다.

새로운 것을 시도 할 때 그러한 주장을 더 잘 표현할 수있는 팁이 있습니까?

예, 주제를 논의하기 전에 자세히 알아보십시오. 토론에 들어가기 전에 좋은 주장과 근거로 자신을 무장 시키십시오.


7

나는 나의 기술을 위해 채용 된 상황에 있었다. 코드를 보았을 때 .. 더 끔찍했습니다. 그런 다음 정리하려고 할 때 더 오래 있었던 사람은 변경 사항을 보지 못합니다. 그 이유는 이점을 볼 수 없기 때문입니다. 당신이 묘사하고있는 것 같습니다. 그 직책을 그만두고 끝났고 이제는 더 나은 연습을하는 회사에서 훨씬 더 발전 할 수 있습니다.

나는 그들이 당신이 팀의 다른 사람들과 함께 더 오래 있기 때문에 역할을해야한다고 생각하지 않습니다. 작업중인 프로젝트에서 팀 관행이 잘못된 관행을 사용하는 것을 보는 경우, imo를 지적해야 할 책임이 있습니다. 그렇지 않다면 당신은 매우 귀중한 자원이 아닙니다. 여러 가지 사항을 지적했지만 아직 아무도 듣지 않는 경우 관리자에게 교체 또는 변경 작업을 요청하십시오. 자신이 나쁜 관행에 적응하지 못하게하는 것이 매우 중요합니다.

실제 질문에

불변의 객체를 사용하는 이유 당신은 당신이 무엇을 다루고 있는지 알고 있기 때문에.

setter를 통해 호스트를 변경할 수있는 db 연결이 전달되었다고 가정하면 연결이 무엇인지 알 수 없습니다. 불변이기 때문에 알고 있습니다.

그러나 지속성에서 검색 한 다음 새 데이터로 재 지속 할 수있는 데이터 구조가 있다고 가정하면이 구조는 변경할 수 없습니다. 엔티티는 동일하지만 값이 변경 될 수 있습니다. 대신 불변의 값 객체 를 인수로 사용하십시오.

그러나 질문에 집중하고있는 것은 생성자에서 종속성을 제거하는 빌더 패턴입니다. 나는 이것에 큰 뚱뚱한 NO 를 말한다 . 인스턴스는 분명히 이미 복잡합니다. 숨기려고하지 말고 고치십시오!

Tl; dr

클래스에 따라 세터를 제거하는 것이 정확할 수 있습니다. 빌더 패턴은 문제점을 해결하는 것이 아니라 숨기고 있습니다. (카펫 아래 먼지가 보이지 않더라도 여전히 존재합니다)


나는 당신의 상황에 대한 세부 사항을 모른다. 그러나 당신이 들어 와서 당신의 기술에 대한 사람들의 자신감을 얻지 못하거나 "왜"를 배우는 데 시간을 들지 않고 모든 것을 바꾸려고한다면, 그들이하는 방식대로 일을한다면 당신은 정확하게 대우 받았다 당신은 거의 모든 회사, 심지어 정말 좋은 회사에서 대우받을 것입니다. 사실, 특히 정말 좋은 사람. 사람들이 누군가의 기술에 자신감을 가지게되면 그것은 단순히 당신의 제안에 대한 설득력있는 사건을 만드는 것입니다. 매력적인 사례를 만들 수 없다면 제안이 그다지 좋지 않을 가능성이 큽니다.
Dunk

1
idk 당신의 가정에 답할 것 @Dunk 나는 모든 것을 바꾸려고하지 않았습니다. 그리고 그들이 무엇을하고 있는지를 아는 사람들은 아니었고, 세계적으로 얼마나 많은 주와 같은 많은 수의 idk와 함께 수백 줄의 코드가있는 클래스와 함수를 자랑스럽게 만들었습니다. 그래서 나는 내 진술을 기다립니다. 당신이 자신에 맞게 나쁜 연습을 채택해야 할 위치에 있음을 알 때 절대 물러서지 마십시오.
superhero

@Dunk 사람들이 팀원으로 코드를 작성하는 방식이 내가하는 일이 아닌 방식으로 변경해보십시오. 그러나 나는 처음부터 그들에게 말한다. "이 프로젝트 에서 코드를 완전히 다시 작성하지 않으면 작동하지 않습니다 ." 그것이 적절하지 않다면, 음 ... 상호입니다. 그것은 단지 안락에 관한 것이 아니라 내가 생산하는 것에 대해 책임을 질 수 있어야한다는 사실에 관한 것입니다. 프로젝트의 주변 코드가 완전히 엉망이라면 그렇게 할 수 없습니다.
슈퍼 히어로

당신은 쓰레기 인 코드로 "영원히"작업 할 필요가없고 단순히 그렇게하는 방식이기 때문에 나쁜 관행을 따를 필요가 없습니다. 그러나 사물을 성공적으로 변경하려면 먼저 신뢰도를 최소로 증명하는 것이 좋습니다. 거의 모든 개발자가 상속 한 코드가 쓰레기라고 생각합니다. 모든 회사가 실제 기술 수준을 몰라도 매번 새로운 직원과 합의하면 쓰레기는 덤프로 바뀝니다. 또한 왜 일이 그랬는지 이해하기 위해 시간을 내야합니다. 때때로 "잘못된"방법은 특정 상황에 대한 "올바른"방법입니다.
Dunk

@ 덩크 나는 당신 이이 문제에 대해 다른 의견을 가지고 있음을 알았습니다. 다른 답변을 읽으면 더 인기있는 것 같습니다. 나는 왜이 답변을 반대하여 썼는지 동의하지 않습니다. 당신이 말한 것은 내 마음을 바꾸지 않았습니다.
슈퍼 히어로

2

다른 모든 답변은 매우 유용하지만 (내 것보다 더 유용합니다) 아직 언급하지 않은 빌더의 속성이 있습니다. 객체 생성을 프로세스로 전환하면 복잡한 논리적 제약 조건을 적용 할 수 있습니다.

예를 들어 특정 필드를 함께 또는 특정 순서로 설정하도록 명령 할 수 있습니다. 이러한 결정에 따라 대상 객체의 다른 구현을 반환 할 수도 있습니다.

// business objects

interface CharRange {
   public char getCharacter();
   public int getFrom();
   public int getTo();
}

class MultiCharRange implements CharRange {
   final char ch;
   final int from;
   final int to;

   public char getCharacter() { return ch; }
   public int getFrom() { return from; }
   public int getTo() { return to; }
}

class SingleCharRange implements CharRange {
   final char ch;
   final int position;

   public char getCharacter() { return ch; }
   public int getFrom() { return position; }
   public int getTo() { return position; }
}

// builders

class Builder1 {
   public Builder2 character(char ch) {
      return new Builder2(ch);
   }
}

class Builder2 {
   final char ch;
   int from;
   int to;

   public Builder2 range(int from, int to) {
      if (from > to) throw new IllegalArgumentException("from > to");
      this.from = from;
      this.to = to;
      return this;
   }

   public Builder2 zeroStartRange(int to) {
      this.from = 0;
      this.to = to;
      return this;
   }

   public CharRange build() {
      if (from == to)
         return new SingleCharRange(ch,from);
      else 
         return new MultiCharRange(ch,from,to);
   }
}

이것은별로 의미가 없지만, 세 가지 속성을 모두 보여줍니다. 문자가 항상 먼저 설정되고 범위 제한이 항상 설정되고 함께 확인되며 빌드시 구현을 선택합니다.

이것이 어떻게 더 읽기 쉽고 안정적인 사용자 코드로 이어질 수 있는지 쉽게 알 수 있지만, 알 수 있듯이 많은 빌더 코드가 있습니다 (스 니펫을 단축하기 위해 생성자를 생략했습니다). 따라서 다음과 같은 질문을하여 절충점을 계산하려고합니다.

  • 한두 곳에서만 개체를 ​​인스턴스화합니까? 이것이 변경 될 가능성이 있습니까?
  • 어쩌면 원래 객체를 더 작은 객체의 구성으로 리팩토링하여 이러한 제약 조건을 적용해야합니까?
  • 메소드에서 메소드로 빌더를 전달하게 될까요?
  • 정적 팩토리 메소드를 대신 사용할 수 있습니까?
  • 외부 API의 일부입니까, 가능한 한 완벽하고 매끄러 워야합니까?
  • 빌더가 있다면 현재 버그에 대한 백 로그를 피할 수 있었던 것은 대략 몇 개입니까?
  • 추가 문서 작성 비용을 얼마나 절약 할 수 있습니까?

동료들은 단순히 트레이드 오프가 유익하지 않다고 결정했습니다. 추상적 원칙에 의지하지 않고이 해결책 또는 그 실제적인 의미에 집중하는 것이 바람직하고 공개적으로 이유를 논의해야합니다.


1
객체 생성을 프로세스로 전환하면 복잡한 논리적 제약 조건을 적용 할 수 있습니다. 밤. 그리고이 모든 것이 더 작고 불연속적이고 간단한 단계 로 구성 될 때의 복잡성을 의미 합니다.
radarbob

2

이 클래스는 실제로 둘 이상의 클래스이며 동일한 파일 / 클래스 정의에 결합 된 것 같습니다. DTO라면 한 번에 인스턴스화하고 변경할 수 없도록해야합니다. 하나의 트랜잭션에서 모든 필드 / 속성을 사용하지 않으면 단일 책임 원칙을 거의 위반하는 것입니다. 더 작고 더 응집력 있고 불변의 DTO 클래스로 나누는 것이 도움이 될 수 있습니다. 아직 깨끗한 코드를 읽지 않았다면 문제를 명확하게 설명하고 변경의 이점을 더 잘 이해하십시오.

문자 그대로 몹 프로그래밍이 아닌 한 (이런 팀에 있다고 들리지 않는 한)위원회 가이 수준에서 코드를 디자인 할 수 있다고 생각하지 않으므로 귀하의 의견에 따라 변경하는 것이 좋습니다 최선의 판단을 한 다음, 잘못 판단한 경우 턱에 가져 가십시오.

그러나 코드의 잠재적 인 문제를 그대로 설명 할 수있는 한, 솔루션이 허용되지 않는 경우에도 솔루션이 필요한지에 대해 여전히 논쟁 할 수 있습니다 . 그러면 사람들은 대안을 자유롭게 제공 할 수 있습니다.

" 약한 견해, 약한 견해 "는 좋은 원칙이다-당신은 당신이 알고있는 것에 기초하여 자신감을 가지고 진행한다. 있다. 틀린 답은 더 나 빠지게하는 것입니다.


코드가 그렇게 나쁜 이유의 일부인위원회가 설계 한 것은 아닙니다. 내가 생각하는 좋은 일이 너무 많아 그것은 이다 DTO하지만 난 조각으로 그것을 파괴하지 않을 것이다; 코드베이스가 나쁘면 DB가 훨씬 나쁘다. 마지막 단락에 +1 (주로).
rath
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.