끊임없이 변화하는 프로젝트에서 디자인 패턴을 사용하지 않아야합니까?


32

저의 친구는 모든 개발자가 싫어하는 프로젝트에서 소규모 회사를 위해 일하고 있습니다. 가능한 빨리 릴리스하도록 압력을 가하고 기술 부채에 관심이있는 유일한 사람이고 고객에게는 기술적 배경이 없습니다.

그는 저와 같은 프로젝트에서 디자인 패턴의 적절성에 대해 생각하게 만드는 이야기를 들려주었습니다. 여기 이야기가 있습니다.

웹 사이트의 다른 곳에 제품을 표시해야했습니다. 예를 들어, 컨텐츠 관리자는 제품을 볼 수 있지만 API를 통해 최종 사용자 또는 파트너도 볼 수 있습니다.

때로는 제품에 정보가 누락 된 경우가 있습니다. 예를 들어 제품을 만들 때 가격이 없었지만 가격이 아직 지정되지 않았습니다. 일부에는 설명이 없습니다 (설명은 수정 이력, 현지화 된 콘텐츠 등이있는 복잡한 개체 임). 일부는 선적 정보가 부족했습니다.

디자인 패턴에 대한 최근의 독서에서 영감을 얻은 것은 이것이 마법의 Null Object 패턴 을 사용할 수있는 훌륭한 기회라고 생각했습니다 . 그래서 나는 그것을했고 모든 것이 부드럽고 깨끗했습니다. product.Price.ToString("c")가격 product.Description.Current을 표시하거나 설명 을 표시 하기 위해 전화 해야했습니다 . 조건부 필요가 없습니다. 언젠가 이해 관계자는 nullJSON 을 사용하여 API에 다르게 표시하도록 요청했습니다 . 또한 "지정되지 않은 가격 [변경]"을 표시하여 콘텐츠 관리자의 경우와는 다릅니다. 그리고 더 이상 필요하지 않기 때문에 사랑하는 Null Object 패턴을 살해해야했습니다.

같은 방식으로 몇 개의 추상 공장과 빌더를 제거해야했고, 기본 인터페이스가 3 개월 동안 하루에 두 번 바뀌었기 때문에 직접 및 못생긴 호출로 아름다운 Facade 패턴을 교체하게되었고 Singleton도 나를 떠났습니다. 요구 사항이 문맥에 따라 관련 대상이 달라야한다고 지시했을 때.

3 주 이상의 작업은 디자인 패턴을 추가 한 다음 한 달 후에 찢어졌으며 마침내 내 코드를 포함하여 다른 사람이 관리 할 수 ​​없을 정도로 스파게티가되었습니다. 처음에는 이러한 패턴을 사용하지 않는 것이 좋지 않습니까?

실제로, 나는 요구 사항이 끊임없이 변하고 제품의 응집력이나 일관성을 염두에 두지 않는 사람들 의해 지시 되는 그러한 유형의 프로젝트에 대해 스스로 일해야했다 . 이러한 맥락에서 얼마나 민첩한지 중요하지 않으며 문제에 대한 우아한 솔루션이 제공 될 것이며, 마지막으로 구현할 때 요구 사항이 크게 바뀌어 우아한 솔루션이 적합하지 않다는 것을 알게됩니다. 더 이상.

이 경우 해결책은 무엇입니까?

  • 디자인 패턴을 사용하지 않고, 생각을 멈추고, 코드를 직접 작성합니까?

    팀이 직접 코드를 작성하는 경험을하는 것이 흥미로울 것입니다. 다른 사람은 입력하기 전에 두 번 생각하고 며칠 후에 원래 디자인을 버릴 위험이 있습니다. 동일한 기술적 부채. 그러한 데이터가 없다면, 나는 20 개월의 월간 프로젝트에서 작업 할 때 사전 생각없이 코드를 입력하는 것이 옳지 않다고 주장 할뿐입니다 .

  • 더 이상 의미가없는 디자인 패턴을 유지하고 새로 만든 상황에 더 많은 패턴을 추가하려고합니까?

    이것은 옳지 않은 것 같습니다. 패턴은 코드 이해를 단순화하는 데 사용됩니다. 너무 많은 패턴을 넣으면 코드가 엉망이됩니다.

  • 새로운 요구 사항을 포함하는 새로운 디자인을 생각한 다음 이전 디자인을 새로운 디자인으로 천천히 리팩토링합니까?

    이론가이자 애자일을 선호하는 사람으로서 나는 그것을 완전히 받아들입니다. 실제로, 매주 화이트 보드로 돌아가서 이전 디자인의 많은 부분을 다시 실행해야 한다는 사실과 고객이 지불 할 충분한 자금이 없거나 기다릴 시간이 충분하지 않다는 것을 알면 아마 작동하지 않을 것입니다.

그래서 어떤 제안?


43
나는 이것이 잘못된 딜레마라고 생각합니다. 친구가 직접 입력하면 코드는 이제 유지할 수없는 스파게티 접시입니다. 그것은 소프트웨어 패턴의 결함이 아닙니다. 친구가 유지 보수성높이고 감소시키지 않는 방식으로 이러한 패턴을 올바르게 사용할 수 없습니다. 구체적인 예를 생각해 낼 수 있다면 적절한 답변을 게시 할 것입니다.
Robert Harvey

5
또한, FWIW에서, 표류 비용에 대한 허용 오차가없는 고객은 변화하는 요구 사항에 대한 비용이 허용되지 않는 한 애자일을하지 않아야합니다.
Robert Harvey

5
내가 디자인 패턴없이 코드를 훨씬 더 빨리 유지 보수가 어려운 상태에 도달했을 것이라고 의심
스티븐 A. 로우를

28
이 질문은 말이되지 않습니다. "디자인 패턴을 피하는"유일한 방법은 소프트웨어를 전혀 쓰지 않는 것입니다. "XYZ Pattern"과 같은 것은 프로그래머가 코드 구조 및 선택에 대한 정보와 조언을보다 편리하게 전달할 수 있도록 일반적인 코딩 전략에 지정된 이름 일뿐입니다. 코드에서 어떤 디자인을 선택하더라도 이름이 주어지고 "디자인 패턴"이라고 불릴 수 있습니다. 반드시 널리 알려진 것은 아니지만 (독특한 디자인을 자랑스러워하고 그 이름과 블로그에 대한 동기를 부여하지 않는 한) 그것 또는 무언가).
Jason C

9
즉, 발을 "발"이라고 부르는 것을 피할 수는 있지만 여전히 발을 가지고 있습니다. "발"이라고하지 않으면 누군가와 발을 말하는 것이 더 어렵습니다. 당신은 "디자인 패턴을 피하고있다"고 생각할 수도 있지만, 괜찮은 디자인이 나오면 물러서서 살펴보면 디자인이 결국 일반적인 명명 된 패턴 중 하나에 적합하다는 것을 알게 될 것입니다. 전화하든 말든
Jason C

답변:


86

이 질문에 잘못된 가정이 있습니다.

  • 디자인 패턴이있는 코드는 올바르게 적용되지만 해당 패턴이없는 코드보다 구현하는 데 더 많은 시간이 필요합니다.

디자인 패턴은 그 자체로 끝나지 않으며, 그 반대가 아니라 당신을 위해 봉사해야합니다. 디자인 패턴으로 인해 코드를 구현하기가 더 이상 어렵거나 최소한 더 잘 진화 할 수없는 경우 (즉, 변화하는 요구 사항에 쉽게 적응할 수 있음) 패턴의 목적이 누락됩니다. 팀이 "삶"을 더 쉽게 만들지 못할 때 패턴을 적용하지 마십시오. 새로운 Null 객체 패턴이 친구가 사용한 시간 동안 친구에게 서비스를 제공했다면 모든 것이 정상이었습니다. 나중에 제거해야한다면 괜찮을 수도 있습니다. Null 객체 패턴이 (올바른) 구현 속도를 늦추면 사용법이 잘못되었습니다. 이 부분에서 지금까지 "스파게티 코드"의 원인을 결론 내릴 수는 없습니다.

  • 고객은 기술적 배경이없고 제품의 응집성 또는 일관성에 신경 쓰지 않기 때문에 책임을 져야합니다

그것은 그의 직업도 잘못이 아닙니다! 당신의 임무는 응집력과 일관성을 관리하는 것입니다. 요구 사항이 하루에 두 번 변경되면 솔루션이 코드 품질을 희생해서는 안됩니다. 고객에게 시간이 얼마나 걸리는지 알려주고 디자인을 "올바로"얻는 데 더 많은 시간이 필요하다고 생각되면 추정치에 충분히 큰 안전 마진을 추가하십시오. 특히 고객에게 압력을가하려고 할 때는 "스콧 티 원칙"을 사용하십시오 . 그리고 기술이 아닌 고객과 노력에 대해 논쟁 할 때, "리팩토링", "단위 테스트", "디자인 패턴"또는 "코드 문서"와 같은 용어는 피하십시오. 말도 안되는 "그는 가치가 없기 때문에. 또는 적어도 고객이 이해할 수있는 기능 (기능, 하위 기능, 동작 변경, 사용자 문서, 오류 수정, 성능 최적화 등).

  • 급변하는 요구 사항에 대한 솔루션은 코드를 빠르게 변경하는 것입니다.

솔직히 "기본 인터페이스가 3 개월 동안 하루에 두 번 변경되는 경우", 하루에 두 번 코드를 변경하여 해결책을 제시해서는 안됩니다. 실제 솔루션은 요구 사항이 자주 변경되는지, 프로세스의 해당 부분에서 변경이 가능한지 묻는 것입니다. 어쩌면 좀 더 선행 분석이 도움이 될 것입니다. 구성 요소 간의 경계가 잘못 선택되어 인터페이스가 너무 넓을 수 있습니다. 때로는 요구 사항의 어느 부분이 안정적이며 아직 논의 중인지에 대한 자세한 정보를 요청하는 데 도움이됩니다 (실제로 논의중인 사항에 대한 구현을 연기합니다). 그리고 때때로 어떤 사람들은 하루에 두 번 마음을 바꾸지 않기 위해 "그들의 엉덩이에 차서"맞아야합니다.


30
+1-기술 솔루션으로 사람들의 문제를 해결할 수 없습니다.
Telastyn

1
+1이지만 "적어도 더 나은 진화 가능 (즉, 변화하는 요구 사항에 쉽게 적응할 수 있음")- 합리적으로 변화하는 요구 사항에 적합합니까?
Fuhrmanator

1
@Fuhrmanator : 이것이 일반적인 용어로 논의하기 어렵다고 생각합니다. IMHO 첫 요구 사항이 "워드 프로세서가 필요하다"고 "비행 시뮬레이터가 필요합니다"로 변경되면 디자인 패턴이 도움이되지 않습니다. 덜 급격한 요구 사항 변경을 위해 소프트웨어를 진화 가능하게 유지할 수있는 방법을 결정하는 것이 항상 쉬운 것은 아닙니다. 가장 좋은 방법은 IMHO가 너무 많은 패턴을 적용하지 말고 일부 원칙-주로 SOLID 원리 및 YAGNI를 적용하는 것입니다. Telastyn은 100 % 요구 사항이 너무 자주 바뀌면 기술적 인 문제가 아니라고 동의합니다.
Doc Brown

4
+1- "정직하게, '기본 인터페이스가 3 개월 동안 하루에 두 번 변경되면'해결책은 하루에 두 번 코드를 변경하여 반응하지 않아야합니다. 실제 해결책은 요구 사항이 자주 바뀌는 묻는 것 입니다. 프로세스의 해당 부분을 변경하는 것이 가능합니다. "끊임없이 새로운 방향을 제시 받으려면 모든 이해 관계자와 함께 앉아 기대를 재확인하는 것이 가장 좋습니다. 차이점을 해결하고 프로젝트에보다 명확한 목표를 부여함으로써 모든 사람의 시간과 돈을 낭비하지 않기를 바랍니다.
krillgar

1
@Cornelius Doc Brown은 구체적이지 않고 어렵다고 말했다. 워드 프로세서에서 비행 시뮬레이터로의 요구 사항은 합리적이지 않습니다. 어떤 디자인 패턴도 도움이되지 않습니다. 그의 예제 사이에는 많은 회색 영역이 있으며 워드 프로세서의 저장 기능에 새로운 파일 형식을 추가하는 것이 매우 합리적입니다. 구체적인 내용이 없으면 논의하기가 어렵습니다. 또한 변경 하고 싶지 않은 것도 아닙니다 . 요구 사항에 따라 이미 설계를 선택했다면 그러한 변경은 어렵습니다. 워드 프로세서와 비행 시뮬레이션은 빠른 선택의 좋은 예입니다.
Fuhrmanator

43

저의 겸손한 의견은 디자인 패턴 사용을 피하거나 피하지 않아야한다는 것입니다.

디자인 패턴은 이름이 주어진 일반적인 문제에 대한 잘 알려져 있고 신뢰할 수있는 솔루션입니다. 그것들은 당신이 생각할 수있는 다른 솔루션이나 디자인과 기술적 인면에서 다르지 않습니다.

문제의 근본 원인은 친구가 "패턴을 포함하여 (이에 국한되지는 않음) 내가 생각할 수있는 가장 좋은 해결책은 무엇인지에 대한 생각 대신"디자인 패턴 적용 또는 적용하지 않는 "관점에서 생각하는 것일 수 있습니다. 알아".

어쩌면이 접근법은 그가 속하지 않은 곳에서 부분적으로 인공적이거나 강제적 인 방식으로 패턴을 사용하게 할 수도 있습니다. 그리고 이것이 혼란을 초래하는 것입니다.


13
+1 "디자인 패턴은 이름이 주어진 일반적인 문제에 대해 잘 알려져 있고 신뢰할 수있는 솔루션입니다. 생각할 수있는 다른 솔루션이나 디자인과 기술적 인면에서 다르지 않습니다." 정확하게. 사람들은 이름이 지정된 디자인 패턴에 사로 잡혀 프로그래머가 코드와 디자인 선택에 대해 서로 쉽게 커뮤니케이션 할 수 있도록 다양한 전략에 지정된 이름을 잊어 버립니다. 이 자세는되어 매우 큰 혼란 - 자주 반드시 도움이되지 않는 문제에 부적절 "패턴을"강제로 시도와 관련.
Jason C

14

Null Object 패턴을 사용하는 예에서는 고객의 요구가 아닌 프로그래머의 요구를 충족했기 때문에 결국 실패했다고 생각합니다. 고객은 상황에 맞는 형태로 가격을 표시해야했습니다. 프로그래머는 일부 표시 코드를 단순화해야했습니다.

따라서 디자인 패턴이 요구 사항을 충족하지 못하는 경우 모든 디자인 패턴이 시간 낭비라고 말하거나 다른 디자인 패턴이 필요하다고 말합니까?


9

실수는 패턴 개체를 사용하는 것보다 제거하는 것이 더 낫습니다. 초기 설계에서 Null 개체는 문제에 대한 해결책을 제공 한 것으로 보입니다. 이것이 최선의 해결책이 아닐 수도 있습니다.

프로젝트에서 일하는 유일한 사람은 전체 개발 프로세스를 경험할 수있는 기회를 제공합니다. 가장 큰 단점은 멘토가 될 사람이 없다는 것입니다. 모범 사례 나 더 나은 사례를 배우고 적용하기 위해 시간을 내면 빨리 보상을받을 수 있습니다. 요령은 언제 배울 습관을 식별하는 것입니다.

product.Price.toString ( 'c') 형식의 체인 참조 는 Demeter of Law를 위반합니다 . 나는이 연습과 관련된 모든 종류의 문제를 보았으며, 그중 많은 것이 null과 관련이 있습니다. product.displayPrice ( 'c')와 같은 메소드는 내부적으로 널 가격을 처리 할 수 ​​있습니다. 마찬가지로 product.Description.Current는 product.displayDescription (), product.displayCurrentDescription ()에 의해 처리 될 수 있습니다. 또는 product.diplay ( 'Current').

컨텍스트에 응답하여 관리자 및 컨텐츠 제공자에 대한 새로운 요구 사항을 처리해야합니다. 사용할 수있는 다양한 접근 방식이 있습니다. 팩토리 메소드는 표시 될 사용자 클래스에 따라 다른 제품 클래스를 사용할 수 있습니다. 다른 접근 방식은 제품 클래스 표시 메소드가 사용자마다 다른 데이터를 구성하는 것입니다.

좋은 소식은 당신이 친구가 물건이 손을 떼고 있다는 것을 알고 있다는 것입니다. 바라건대, 그는 개정 관리에 코드가 있습니다. 이것은 그가 나쁜 결정을 철회 할 수있게 해줄 것이며, 그는 항상 결정을 내릴 것입니다. 학습의 일부는 다른 접근법을 시도하는 것이며, 그 중 일부는 실패합니다. 앞으로 몇 개월을 처리 할 수 ​​있다면 인생을 단순화하고 스파게티를 청소하는 접근법을 찾을 수 있습니다. 그는 매주 한 가지를 고치기 위해 노력할 수있었습니다.


2
또한 Demeter의 법칙을 "파괴해야"하고 표면에 사용 된 모델이 적합하지 않음을 더 나타낼 수도 있습니다. 왜 "뷰 모델"(느슨한 의미로 사용됨)에 표시 할 설명이 없는가? (즉, UI 수준에서 현재 설명보다 더 많은 이유가 무엇입니까?) 비즈니스 계층은 관리자인지 여부에 따라 이미 다른 내용이있는 UI 계층에 적절히 채워진 개체를 준비 할 수 있습니다.
Cornelius

7

이 질문은 많은 점에서 잘못된 것 같습니다. 그러나 뻔뻔한 사람들은 다음과 같습니다.

  • 언급 한 Null 개체 패턴의 경우 요구 사항이 변경된 후 약간의 코드가 변경됩니다. 괜찮지 만 Null 개체 패턴을 '살해'한다는 의미는 아닙니다.

많은 사람들이 디자인 패턴은 일반적인 관행에 라벨을 붙이고 이름을 짓는 것에 관한 것이라고 많은 사람들이 올바르게 말했습니다. 따라서 셔츠에 대해 생각해보십시오. 셔츠에는 칼라가 있습니다. 어떤 이유로 칼라 또는 칼라의 일부를 제거합니다. 이름과 라벨이 바뀌지 만 여전히 셔츠입니다. 이것은 정확히 여기에 해당합니다. 사소한 변경이 있어도 해당 패턴을 '살인'한 것은 아닙니다. (다시 말해서)

  • 요구 사항 변경이 사소한 일이 될 때 모든 곳에서 대규모 전략적 디자인 변경을 수행하기 때문에 이야기 한 디자인이 나쁩니다. 높은 수준의 비즈니스 문제가 변경되지 않으면 대규모 디자인 변경을 정당화 할 수 없습니다.

내 경험상 사소한 요구 사항이 올 때 코드베이스의 작은 부분 만 변경하면됩니다. 일부는 약간 해킹이 될 수 있지만 유지 관리 성 또는 가독성에 실질적으로 영향을 미치기에는 너무 심각하지 않으며 종종 해키 부분을 설명하는 몇 줄의 주석으로 충분합니다. 이것은 매우 일반적인 관행입니다.


7

잠시 멈추고 여기서 근본적인 문제를 살펴 보자- 아키텍처 모델이 시스템의 저수준 기능에 너무 결합되어 개발 프로세스에서 아키텍처가 자주 중단되는 시스템 설계.

건축과 관련된 디자인과 디자인 패턴의 사용은 적절한 수준에 있어야하며 올바른 수준에 대한 분석은 사소한 것이 아니라는 것을 기억해야합니다. 한편으로는 "MVC"등과 같은 매우 기본적인 제약 조건만으로 시스템 아키텍처를 너무 높은 수준으로 쉽게 유지할 수 있으므로 명확한 지침 및 코드 활용과 같은 기회를 놓칠 수 있으며 스파게티 코드가 쉽게 모든 여유 공간에서 번성하십시오.

반면에 제약 조건을 세부 수준으로 설정하는 것처럼 시스템을 지나치게 과도하게 설계 할 수 있습니다. 실제로 예상보다 제한적이며 제약 조건을 지속적으로 위반하는 제약 조건에 의존 할 수 있다고 가정합니다. 절망하기 시작할 때까지 끊임없이 개조하고 재건해야합니다.

시스템 요구 사항의 변경은 항상 적거나 그보다 더 커질 것입니다. 그리고 아키텍처 및 디자인 패턴을 사용하면 얻을 수있는 잠재적 인 이점이 항상 존재하므로 디자인 패턴을 사용하는 것에 대한 문제는 아니지만, 어느 수준에서 사용해야하는지에 대한 의문이 있습니다.

이를 위해서는 제안 된 시스템의 현재 요구 사항을 이해해야 할뿐만 아니라 시스템의 어떤 측면이 시스템의 안정적인 핵심 속성으로 간주되는지, 개발 과정에서 어떤 속성이 변경 될 수 있는지 식별해야합니다.

조직화되지 않은 스파게티 코드로 끊임없이 싸워야한다는 것을 알게되면 충분한 아키텍처를 구축하지 않았거나 높은 수준에서 수행하고있을 것입니다. 아키텍처가 자주 중단되는 것을 발견하면 아마도 너무 자세한 아키텍처를 수행하는 것입니다.

건축과 디자인 패턴의 사용은 책상을 페인트하는 것처럼 시스템을 "코팅"할 수있는 것이 아닙니다. 그것들은 당신이 의존해야 할 제약 조건이 안정적 일 가능성이 높은 수준에서, 그리고 이러한 기술이 실제로 아키텍처를 모델링하고 실제 제약 조건 / 아키텍처 / 패턴을 구현하는 데 어려움이있는 수준에서 신중하게 적용되어야하는 기술입니다. 코드로.

너무 자세한 아키텍처 문제와 관련하여 가치가 높지 않은 아키텍처에 많은 노력을 기울일 수 있습니다. 참고로 위험 중심 아키텍처를 참조하십시오.이 책이 마음에 듭니다.- 충분한 소프트웨어 아키텍처 , 아마도 당신도 마찬가지입니다.

편집하다

필자가 종종 "너무 자세한 아키텍처"를 의미하는 "너무 많은 아키텍처"라고 표현한 것을 깨달았을 때 대답이 명확 해졌다. 너무 자세한 아키텍처는 종종 "너무 많은"아키텍처로 보일 수 있지만 아키텍처를 좋은 수준으로 유지하고 가장 아름다운 시스템 인류를 만들어 낸 경우에도 우선 순위가 기능 및 출시 시간에 대해


+1 이것들은 시스템에서보아야한다고 생각하는 매우 높은 수준에 대한 아주 좋은 생각이지만 소프트웨어 디자인에 많은 경험이 필요합니다.
사무엘

4

친구가 그의 일화를 바탕으로 수많은 역풍에 직면하고있는 것 같습니다. 그것은 불행한 일이며 작업하기가 매우 어려운 환경 일 수 있습니다. 어려움에도 불구하고, 그는 인생을 더 쉽게 만들기 위해 패턴을 사용하는 올바른 길을 가고 있었으며, 그 길을 떠난 것은 부끄러운 일입니다. 스파게티 코드는 최고의 결과입니다.

기술 및 대인 관계의 두 가지 문제 영역이 있으므로 각 문제를 개별적으로 다룰 것입니다.

대인 관계

친구가 겪고있는 어려움은 빠르게 변화하는 요구 사항과 그것이 유지 관리 가능한 코드를 작성하는 능력에 어떻게 영향을 미치는지입니다. 먼저, 하루에 두 번, 매일 그렇게 긴 시간 동안 변화하는 요구 사항은 더 큰 문제이며 비현실적인 암시 적 기대가 있다고 말하고 싶습니다. 코드가 변경할 수있는 보다 요구 사항이 빠르게 변하고 있습니다. 코드 또는 프로그래머가 계속 유지할 것으로 기대할 수 없습니다. 이러한 빠른 변화 속도는 원하는 제품에 대한 불완전한 개념이 더 높은 수준에서 나타납니다. 이것은 문제입니다. 그들이 정말로 무엇을 원하는지 모른다면, 절대 그것을 얻기 위해 많은 시간과 돈을 낭비 할 것입니다.

변경 경계를 설정하는 것이 좋습니다. 2 주마다 변경 사항을 그룹으로 묶은 다음 구현하는 동안 2 주 동안 동결합니다. 다음 2 주 동안 새 목록을 작성하십시오. 이러한 변경 사항 중 일부가 겹치거나 모순되는 느낌이 듭니다 (예 : 두 옵션 사이에서 앞뒤로 흔들림). 변화가 빠르고 격렬 해지면 모두 우선 순위가 높습니다. 이들이 목록에 누적되도록하면 노력과 생산성을 극대화하는 데 가장 중요한 것을 구성하고 우선 순위를 정하기 위해 그들과 함께 작업 할 수 있습니다. 그들은 그들의 변화 중 일부가 어리 석거나 덜 중요하여 친구에게 호흡 공간을주는 것을 볼 수 있습니다.

그러나 이러한 문제로 인해 좋은 코드를 작성하지 못하게해서는 안됩니다. 잘못된 코드는 문제를 악화시킵니다. 한 솔루션에서 다른 솔루션으로 리팩토링하는 데 시간이 걸릴 수 있지만 가능한 사실은 패턴과 원칙을 통해 좋은 코딩 방법의 이점을 보여줍니다.

빈번한 변화가있는 환경에서는 기술 부채 발생할 입니다. 타월에 던지기보다 너무 지불하는 것이 훨씬 낫고 극복하기에는 너무 커질 때까지 기다리십시오. 패턴이 더 이상 유용하지 않으면 리팩토링하지만 카우보이 코딩 방식으로 돌아 가지 마십시오.

인위적인

친구가 기본 디자인 패턴을 잘 알고있는 것 같습니다. Null 개체는 그가 직면 한 문제에 대한 좋은 접근 방식입니다. 사실, 그것은 여전히 ​​좋은 접근법입니다. 그가 어려움을 겪는 것처럼 보이는 이유 는 패턴 뒤에있는 원칙, 그 이유 에 대한 이해 입니다. 그렇지 않으면, 그가 접근을 포기했을 것이라고는 생각하지 않습니다.

(다음은 원래 질문에서 요구되지 않았지만 예시 목적으로 패턴을 준수하는 방법을 보여주는 일련의 기술 솔루션입니다.)

null 객체의 기본 원리는 다양한 것을 캡슐화 한다는 개념입니다 . 변경 사항을 숨기므로 다른 곳에서는 처리 할 필요가 없습니다. 여기서 null 객체는 product.Price인스턴스의 분산을 캡슐화 했습니다 (이를 Price객체 라고 부르고 null 객체 가격은입니다 NullPrice). Price비즈니스 개념 인 도메인 개체입니다. 때로는 비즈니스 로직에서 가격을 아직 모릅니다. 이런 일이 발생합니다. null 객체의 완벽한 유스 케이스. 가격을 출력 Price하는 ToString메소드가 있거나 알 수없는 경우 빈 문자열이거나 빈 문자열을 NullPrice#ToString리턴합니다. 이것은 합리적인 행동입니다. 그런 다음 요구 사항이 변경됩니다.

nullAPI보기에 a를 출력 하거나 관리자보기에 다른 문자열 을 출력해야합니다 . 이것이 우리의 비즈니스 로직에 어떤 영향을 미칩니 까? 글쎄요. 위의 진술에서 'view'라는 단어를 두 번 사용했습니다. 이 단어는 분명하게 말하지 않았지만 요구 사항에서 숨겨진 단어를 들으려면 스스로 훈련해야합니다. 그렇다면 왜 '보기'가 그렇게 중요한가? 변화가 실제로 어디에서 일어나야 하는지 알려주기 때문 입니다.

제쳐두고 : 우리가 MVC 프레임 워크를 사용하는지 여부는 여기와 관련이 없습니다. MVC는 'View'에 대해 매우 구체적인 의미를 갖지만 프레젠테이션 코드의보다 일반적인 의미로 사용하고 있습니다.

뷰에서이 문제를 해결해야합니다. 우리는 어떻게 할 수 있습니까? 가장 쉬운 방법은 if진술입니다. null 객체가 모든 if를 제거하기위한 것이지만 우리는 실용적이어야합니다. 문자열이 비어 있는지 확인하고 전환 할 수 있습니다.

if(product.Price.ToString("c").Length == 0) { // one way of many
    writer.write("Price unspecified [Change]");
} else {
    writer.write(product.Price.ToString("c"));
}

이것이 캡슐화에 어떤 영향을 줍니까? 여기서 가장 중요한 부분은 뷰 로직이 뷰에 캡슐화되어 있다는 것 입니다. 이러한 방식으로 비즈니스 로직 / 도메인 객체를 뷰 로직의 변경 사항과 완전히 격리시킬 수 있습니다. 추악하지만 작동합니다. 그러나 이것이 유일한 옵션은 아닙니다.

가격이 설정되지 않은 경우 기본 문자열을 출력하기 위해 비즈니스 로직이 약간 변경되었다고 말할 수 있습니다. 우리는 우리의 Price#ToString방법 을 약간 조정할 수 있습니다 (실제로 과부하 된 방법을 만듭니다). 기본 반환 값을 수락하고 가격이 설정되어 있지 않은 경우 반환 할 수 있습니다.

class Price {
    ...
    // A new ToString method
    public string ToString(string c, string default) {
        return ToString(c);
    }
    ...
}

class NullPrice {
    ...
    // A new ToString method
    public string ToString(string c, string default) {
        return default;
    }
    ...
}

이제 뷰 코드는 다음과 같습니다.

writer.write(product.Price.ToString("c", "Price unspecified [Change]"));

조건이 사라졌습니다. 그러나이 작업을 너무 많이 수행하면 특수 사례 메소드가 도메인 객체로 확산 될 수 있으므로이 경우가 거의없는 경우에만 의미가 있습니다.

대신 부울을 반환 하는 IsSet메서드를 만들 수 있습니다 Price.

class Price {
    ...
    public bool IsSet() {
        return return true;
    }
    ...
}

class NullPrice {
    ...
    public bool IsSet() {
        return false;
    }
    ...
}

로직보기 :

if(product.Price.IsSet()) {
    writer.write(product.Price.ToString("c"));
} else {
    writer.write("Price unspecified [Change]");
}

우리는 관점에서 조건부로 돌아 오는 것을 보았지만 가격이 설정되어 있는지를 알려주는 비즈니스 로직의 경우가 더 강합니다. 사용 가능한 Price#IsSet다른 곳에서 사용할 수 있습니다.

마지막으로, 우리는 견해를 돕는 도우미에게 가격을 제시한다는 아이디어를 요약 할 수 있습니다. 이것은 우리가 원하는만큼 도메인 객체를 유지하면서 조건부를 숨길 것입니다.

class PriceStringHelper {
    public PriceStringHelper() {}

    public string PriceToString(Price price, string default) {
        if(price.IsSet()) { // or use string length to not change the Price class at all
           return price.ToString("c");
        } else {
            return default;
        }
    }
}

로직보기 :

writer.write(new PriceStringHelper().PriceToString(product.Price, "Price unspecified [Change]"));

변화를 만들기 위해 더 많은 가지 방법이 있습니다 (우리가 일반화 할 수있는 PriceStringHelper객체로는 반환 문자열이 비어있는 경우 기본), 그러나 이들은 (대부분의) 보존 몇 가지 간단한 것들 패턴 모두 원칙, 등 뿐만 아니라 그러한 변화를 만드는 실질적인 측면도 있습니다.


3

디자인 패턴의 복잡성으로 인해 해결해야 할 문제가 갑자기 사라지면 물릴 수 있습니다. 안타깝게도 디자인 패턴의 열정과 인기로 인해 이러한 위험은 거의 드러나지 않습니다. 친구의 일화는 패턴이 어떻게 돈을 지불하지 않는지를 보여줍니다. Jeff Atwood는 주제에 대한 몇 가지 선택 단어 를 가지고 있습니다 .

요구 사항의 문서 변동 점 (위험이 있음)

보다 복잡한 디자인 패턴 (Null Object는별로 많지 않음)에는 보호 된 변형 개념이 포함되어 있습니다. 즉 , "예측 된 변형 또는 불안정성의 지점을 식별하고, 주변에 안정적인 인터페이스를 만드는 책임을 할당합니다." 어댑터, 방문자, 외관, 레이어, 관찰자, 전략, 데코레이터 등이 모두이 원칙을 이용합니다. 소프트웨어가 예상되는 변동성의 차원에서 확장되어야 할 때 "지급"하고 "안정한"가정은 안정적으로 유지됩니다.

요구 사항이 너무 불안정하여 "예측 변형"이 항상 잘못되면 적용하는 패턴이 고통을 유발하거나 불필요하게 복잡해집니다.

Craig Larman은 보호 변형을 적용 할 수있는 두 가지 기회에 대해 말합니다.

  • 변형 지점 -기존, 현재 시스템 또는 지원해야하는 여러 인터페이스와 같은 요구 사항
  • 진화 점 -기존 요구 사항에 존재하지 않는 추론 적 변동 점.

둘 다 개발자가 문서화해야하지만 변형 점에 대한 고객의 약속이 있어야합니다.

위험을 관리하기 위해 PV를 적용한 모든 디자인 패턴을 고객이 서명 한 요구 사항의 변동 지점에서 추적해야한다고 말할 수 있습니다. 고객이 요구 사항의 변동 점을 변경하는 경우 해당 변동을 지원하기 위해 설계 [패턴]에 투자했을 가능성이 있기 때문에 설계가 크게 변경되어야 할 수도 있습니다. 응집력, 커플 링 등을 설명 할 필요가 없습니다.

예를 들어, 고객은 소프트웨어가 세 가지 다른 레거시 인벤토리 시스템에서 작동하기를 원합니다. 그것은 당신이 디자인하는 변형 점입니다. 고객이 해당 요구 사항을 충족시키지 못하면 쓸모없는 디자인 인프라가 있습니다. 고객은 변형 포인트에 비용이 든다는 것을 알아야합니다.

CONSTANTS 소스 코드에서 간단한 형태의 PV

귀하의 질문에 대한 또 다른 비유 CONSTANTS는 소스 코드에서 사용 하는 것이 좋은 아이디어 인지 묻는 것입니다. 이 예를 참조 하여 고객이 비밀번호 필요성을 제거했다고 가정 해 보겠습니다. 따라서 MAX_PASSWORD_SIZE코드 전체에 지속적으로 퍼져 나가면 쓸모 없게되고 유지 관리 및 가독성에 방해가 될 수 있습니다. CONSTANTS이유를 사용한다고 비난 하시겠습니까 ?


2

나는 그것이 당신의 상황의 본질에 적어도 부분적으로 달려 있다고 생각합니다.

끊임없이 변화하는 요구 사항을 언급했습니다. 고객이 "이 꿀벌 관리 응용 프로그램이 말벌과도 함께 작동하기를 원합니다"라고 말하면 이는 신중한 디자인이 진행을 방해하는 것이 아니라 진전을 도울 수있는 상황처럼 보입니다 (특히 미래에 그녀가 초파리도 유지하십시오.)

반면에, 변경의 본질이 "이 양봉 관리 응용 프로그램이 내 세탁실 대기업의 급여를 관리하기를 원합니다"와 더 유사하면 코드의 양이 당신의 구멍을 파고 들지 않습니다.

디자인 패턴에는 본질적으로 좋은 점이 없습니다. 도구는 다른 도구와 마찬가지로 도구를 사용하여 중장기 작업을보다 쉽게 ​​수행 할 수 있습니다. 다른 도구 (예 : 의사 소통 또는 연구 )가 더 유용한 경우이를 사용합니다.

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