“type”속성을 가진 엔티티가 있다고 가정하십시오. 20 가지 이상의 가능한 유형이있을 수 있습니다.
이제 유일하게 유스 케이스 인 A-> B에서 유형을 변경할 수있는 것을 구현하라는 요청을 받았습니다.
그렇다면 유효한 유형이라면 임의의 유형 변경을 허용하는 것을 구현해야합니까? 또는 요구 사항에 따라 A-> B에서 변경하고 B-> A 또는 A-> C와 같은 다른 유형 변경을 거부해야합니까?
장단점에서 장단점을 볼 수 있습니다. 일반적인 솔루션은 앞으로 비슷한 요구 사항이 발생할 경우 작업이 줄어 들지만 잘못 될 가능성이 더 큽니다. 포인트).
특정 솔루션은 오류가 덜 발생하지만 비슷한 요구 사항이 발생하면 향후 더 많은 작업이 필요합니다.
나는 좋은 개발자가 변화를 예상하고 시스템을 설계하여 앞으로 쉽게 확장 할 수 있도록 노력해야한다고 들었습니다. 일반적인 솔루션 인 것 같습니다.
편집하다:
특정 적이 지 않은 예제에 더 많은 세부 정보 추가 :이 경우 “일반”솔루션은 “특정”솔루션보다 적은 작업이 필요합니다. 특정 솔루션은 기존 유형과 새 유형에 대한 유효성 검증이 필요하지만 일반 솔루션은 필요합니다. 새 유형의 유효성 검사 만하면됩니다.
답변
내 경험 법칙 :
- 문제가 처음 발생하면 특정 문제 만 해결하십시오 ( YAGNI 원칙).
- 두 번째로 동일한 문제가 발생하면 많은 작업이 없다면 첫 번째 사례를 일반화하는 것을 고려하십시오.
- 일반화 된 버전을 사용할 수있는 세 가지 특정 사례가 있으면 실제로 일반화 된 버전 계획을 시작해야합니다. 이제는 실제로 일반화 할 수있을만큼 문제를 충분히 이해해야합니다.
물론 이것은 지침이며 엄격하지 않은 규칙은 아닙니다. 실제 답변은 사례별로 최선의 판단을하는 것입니다.
답변
유사한 솔루션이 필요한 경우 특정 솔루션 […]은 향후 더 많은 작업이 필요합니다.
나는이 주장을 수십 번 들었고, 내 경험에 따르면, 그것은 정기적으로 오해 인 것으로 판명되었다. 지금 또는 나중에 일반화하면 두 번째 유사한 요구 사항이 발생하면 작업의 총계는 거의 동일합니다. 따라서 이러한 노력이 효과가 있을지 모를 경우 일반화에 추가 노력을 기울일 필요가 없습니다.
(이것은 더 일반적인 솔루션이 덜 복잡하고 특정 솔루션보다 노력이 덜 필요할 때 적용되지 않지만 내 경험상 이러한 경우는 드문 경우입니다. 그런 종류의 시나리오는 나중에 질문으로 편집되었으며, 그렇지 않습니다. 내 대답에 관한 것입니다).
“두 번째 유사한 사례”가 나타나면 일반화에 대해 생각할 때입니다. 이 두 번째 요구 사항은 올바른 것을 일반적인 것으로 만들 었는지 확인할 수있는 시나리오를 제공하므로 올바르게 일반화하는 것이 훨씬 쉽습니다 . 한 경우에 대해서만 일반화하려고하면 어두운 곳에서 촬영됩니다. 일반화 할 필요가없는 특정 항목을 과도하게 일반화하고 다른 부분을 그리워 할 가능성이 높습니다. 그리고 두 번째 사례가 발생하고 잘못된 것을 일반화했다는 것을 알게 되면이를 해결하기 위해 훨씬 더 많은 작업 을해야합니다.
그래서 나는 “경우에 따라”일을하고 싶은 유혹을 늦추는 것이 좋습니다. 이 접근 방식은 세 번, 네 번 이상 일반화 할 기회를 놓친 다음 유지 보수 할 유사한 모양의 중복 코드가있는 경우에만 더 많은 작업과 유지 보수 노력을하게됩니다.
답변
TL; DR : 해결하려는 대상에 따라 다릅니다.
C #의 Func 와 Action이 얼마나 멋진 지에 대해 이야기하는 동안 Gramps와 비슷한 대화를 나 ve습니다 . My Gramps는 매우 오래된 타이머 프로그래머로, 소프트웨어가 방 전체를 차지한 컴퓨터에서 실행 된 이후 소스 코드 주변에있었습니다.
그는 인생에서 기술을 여러 번 바꿨습니다. 그는 C, COBOL, Pascal, BASIC, Fortran, Smalltalk, Java로 코드를 작성했으며 결국 C #을 취미로 시작했습니다. 필자는 IBM의 SideKick의 파란색 편집기에서 코드의 첫 줄을 새기면서 슬프게도 무릎에 앉아 프로그래밍하는 방법을 배웠다. 내가 20 살이되었을 때, 나는 이미 밖에서 연주하는 것보다 코딩에 더 많은 시간을 보냈다.
그것들은 약간의 추억이므로, 실마리를 밝히지 않을 때 실례합니다. 나는 그 순간을 좋아합니다.
그가 저에게 말한 것입니다.
“문제의 일반화를 위해 가야합니까 아니면 특정 범위에서 문제를 해결해야합니까? 그렇지 않습니까? 질문입니다.”
Gramps는 잠시 동안 안경에 대한 생각을 잠시 멈추고 안경의 위치를 얼굴에 고정시켰다. 그는 오래된 사운드 시스템에서 Deep Purple의 LP를 들으면서 컴퓨터에서 매치 3 게임을하고있었습니다.
“글쎄, 그것은 당신이 해결하려는 문제에 달려있다”고 말했다. “모든 디자인 선택을위한 하나의 거룩한 솔루션이 존재한다고 믿기 힘들지만, 하나도 없습니다. 소프트웨어 아키텍처는 치즈와 같습니다.”
“… 치즈, 그램즈?”
“당신이 가장 좋아하는 것에 대해 어떻게 생각하든 상관없이 항상 냄새가 나다고 생각하는 사람이있을 것이다.”
나는 잠시 혼란스러워했지만 Gramps가 계속 진행되고 있다고 말할 수 있기 전에.
“자동차를 만들 때 부품의 재료를 어떻게 선택합니까?”
“나는 … 나는 그것이 관련된 비용과 그 부분이 무엇을해야하는지에 달려 있다고 생각한다.”
“부품이 해결하려는 문제에 따라 달라집니다. 강철로 만든 타이어 나 가죽으로 만든 앞 유리를 만들지 않을 것입니다. 현재 직면하고있는 문제를 가장 잘 해결할 수있는 재료를 선택하십시오. 이제는 무엇입니까? 일반적인 솔루션 또는 특정 솔루션 어떤 문제, 어떤 유스 케이스, 한 번만 사용할 코드에 최대한의 유연성을 부여하기 위해 완전한 기능적 접근 방식을 취해야합니까? 자동차의 일부를 위해 선택하는 재료 또는 작은 집을 짓기 위해 선택한 레고 벽돌의 모양과 같은 디자인 선택과 같은 디자인 선택 “최고의 레고 벽돌은 무엇입니까?”
노인 프로그래머는 계속하기 전에 테이블에 가지고있는 작은 레고 기차 모델을 찾았습니다.
” 벽돌이 필요한 것이 무엇인지 아는 경우에만 대답 할 수 있습니다 . 특정 솔루션이 일반적인 솔루션보다 나은지, 또는 그 반대인지, 어떤 문제인지조차 모를 경우 어떻게 알 수 있습니까? 이해하지 못하는 과거의 선택을 볼 수 없습니다. ”
“.. 방금 매트릭스를 인용 했습니까? “
“뭐?”
“아무것도하지 않습니다.”
“음, 국가 송장 시스템에 무언가를 만들려고한다고 가정 해 봅시다.이 지옥의 API와 3 만 라인의 XML 파일이 내부에서 어떻게 보이는지 알고 있습니다. 해당 파일을 만들기위한 ‘일반적인’솔루션은 어떻게 보일까요? 파일에는 선택적 매개 변수가 포함되어 있으며 매우 특정한 비즈니스 지점에서만 사용해야하는 경우가 많습니다. 대부분의 경우 안전하게 무시할 수 있습니다. 유일한 경우에는 일반 송장 시스템을 만들 필요가 없습니다. 구두를 판매 할 것입니다. 신발을 판매하기위한 시스템을 만들어 그 중에서도 최고의 신발 판매 송장 시스템으로 만드십시오. 이제 모든 유형의 고객을 위해보다 광범위한 응용 프로그램에서 송장 시스템을 만들어야하는 경우- 독립적 인 일반 판매 시스템으로 재판매예를 들어, 이제 가스, 음식 또는 알코올에만 사용되는 옵션을 구현하는 것이 흥미 롭습니다.이제는 가능한 사용 사례입니다. 그것들이 단지 가상의 사용 사례가 아니기 전에는 사용하지 않는 사례를 구현하고 싶지 않습니다 . 사용하지 마십시오 의 동생입니다 필요가 없습니다 . “
Gramps는 레고 기차를 다시 제자리에 놓고 경기 3 게임으로 돌 렸습니다.
“따라서 주어진 문제에 대해 일반적인 솔루션이나 특정 솔루션을 선택할 수 있으려면 먼저 그 문제가 무엇인지 이해해야합니다. 그렇지 않으면 그냥 추측하고 추측하는 것은 프로그래머가 아닌 관리자의 일입니다. “IT의 모든 것이 달려 있습니다.”
그래서 거기 있습니다. “그것은 달려있다”. 그것은 아마도 소프트웨어 디자인을 생각할 때 가장 강력한 두 단어 표현 일 것입니다.
답변
기본적으로 이러한 변화가 일어날 가능성이 있는지 예상해야합니다.
그렇지 않은 경우 일반적으로 간단한 솔루션을 사용하고 나중에 확장하는 것이 좋습니다. 그때 필요한 것에 대해 훨씬 더 명확하게 이해할 수있을 것입니다.
답변
새로운 영역에서 일하고 있다면 Daniel Pryden이 언급 한 3 가지 규칙 보다 분명히 적용해야합니다. 결국, 당신이 그 지역의 초보자라면 어떻게 유용한 추상화를 구축해야합니까? 사람들은 종종 추상화를 잡을 수있는 능력에 대해 스스로 확신하지만, 드물게는 그렇지 않습니다. 내 경험에 따르면, 조기 추상화는 코드 복제보다 악한 일이 아닙니다. 잘못된 추상화는 이해하기가 정말 고통 스럽습니다. 때로는 리팩토링하기가 더 고통 스럽습니다.
이 책 개발자가에서 일하고 알 수없는 영역에 대한 내 포인트 주소는.입니다 추출 유용한 추상화와 특정 도메인으로 구성되어 있습니다.
답변
질문 본문의 특성을 감안할 때, 올바르게 이해했다고 가정하면 실제로는 일반적인 솔루션과 특정 솔루션에 대한 질문보다 중앙 시스템 기능의 디자인 질문으로 간주됩니다.
그리고 중앙 시스템 기능과 관련하여 가장 신뢰할 수있는 것은 존재하지 않는 것입니다. 미니멀리즘의 측면에서 잘못을 저지르고, 특히 시스템과의 작업이 훨씬 어려워 졌기 때문에 많은 의존성이있는 문제가있는 기능을 오랫동안 원하지 않는 것을 제거하는 것보다 일반적으로 원하는 기능을 중앙에서 오랫동안 선호하는 것이 더 쉽다는 점을 고려하면 각각의 새로운 기능으로 끝없는 디자인 문제를 제기하는 동안 필요합니다.
사실, 앞으로 이것이 자주 필요할지 여부에 대한 강한 기대가 없기 때문에 가능한 경우 이것을 A에서 B로 대체하는 것으로 보지 않고 대신 A의 상태를 변환하는 방법으로 찾고자합니다. 예를 들어, A의 일부 필드를 설정하여 실제로 다른 ‘유형’으로 변경하지 않고 사용자에게 변형되고 B처럼 보이도록 할 수 있습니다. A의 상태 일 때 컴포지션을 사용하여 개인적으로 A 저장소 B를 만들고 B에서 함수를 호출 할 수 있습니다 는 가능한 경우 구현을 단순화하기 위해 B를 모방해야 함을 나타내도록 설정됩니다. 그것은 매우 간단하고 최소한의 침습적 솔루션이어야합니다.
어쨌든 많은 다른 사람들을 에코 하면서이 경우 일반적인 솔루션을 피하는 편을 잘못 제안 할 것이지만, 더 중요한 것은 중앙 시스템에 매우 대담한 기능을 추가하는 것을 고려하고 있기 때문입니다. 특히 지금은 그것을 떠나는 측면에서 실수하는 것이 좋습니다.
답변
이 특정 문제에 대한 일반적인 대답은 어렵습니다 😉
일반적 일수록 향후 변경에 더 많은 시간을 투자하게됩니다. 예를 들어, 많은 게임 프로그램 은 게임에서 캐릭터와 오브젝트의 매우 정교하지만 엄격한 유형의 시스템을 구축하는 대신 엔티티 구성 요소 패턴을 사용합니다 .
다른 한편으로, 일반적인 것을 만들기 위해서는 매우 구체적인 것보다 훨씬 높은 설계에 선행 시간과 노력 투자가 필요합니다. 이로 인해 과도한 엔지니어링 및 미래의 잠재적 요구 사항에서 길을 잃을 위험이 있습니다.
항상 당신에게 획기적인 일반화가 있는지 볼 가치가 있습니다. 그러나 결국, 그것은 지금 당신이 소비 할 수있는 노력과 미래에 필요할 수있는 노력 사이의 균형에 관한 문제입니다.