"소프트 코딩"이란 무엇입니까?


87

에서 이 문서 알렉스 Papadimoulis으로,이 조각을 볼 수있다 :

private void attachSupplementalDocuments()
{
  if (stateCode == "AZ" || stateCode == "TX") {

    //SR008-04X/I are always required in these states
    attachDocument("SR008-04X");
    attachDocument("SR008-04XI");
  }

  if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

  if (coInsuredCount >= 5  && orgStatusCode != "CORP") {
    //Non-CORP orgs with 5 or more co-ins require AUTHCNS-1A
    attachDocument("AUTHCNS-1A");
  }
}

나는이 기사를 정말로 이해하지 못한다.

나는 인용한다 :

모든 비즈니스 규칙 일정이 일부 구성 파일에 저장 한 경우, 생활이 많은 것 [이상 ( 원문 )] 어려운 소프트웨어 유지 보수 모두를위한 하나, 큰 파일을 공유 코드 파일이 많이있을 것를 (또는 그 반대, 아주 작은 구성 파일들); 비즈니스 규칙에 변경 사항을 배치하려면 새 코드가 필요하지 않지만 구성 파일을 수동으로 변경해야합니다. 디버깅이 훨씬 더 어렵습니다.

이는 구성 파일에 "500000"상수 정수 또는 "AUTHCNS-1A"및 기타 문자열 상수를 갖는 것에 대한 인수입니다.

이것이 어떻게 나쁜 습관이 될 수 있습니까?

이 스 니펫에서 "500000"은 숫자가 아닙니다. 예를 들어 다음과 동일하지 않습니다.

int doubleMe(int a) { return a * 2;}

여기서 2는 추상화 할 필요가없는 숫자입니다. 그 사용법은 분명하며 나중에 재사용 할 수있는 것은 아닙니다.

반대로 "500000"은 단순한 숫자가 아닙니다. 기능의 중단 점에 대한 아이디어를 나타내는 중요한 가치입니다. 이 번호는 여러 곳에서 사용할 수 있지만 사용중인 번호는 아닙니다. 그것은 어떤 규칙이 적용되는지, 어떤 규칙이 적용되는지에 대한 한계 / 경계선에 대한 아이디어입니다.

방법도 구성 파일에서 참조하거나하는 #define, const또는 언어는 그 값을 포함하여보다 악화 제공 무엇? 나중에 프로그램이나 다른 프로그래머가 그 경계선을 필요로하므로 소프트웨어가 다른 선택을 수 있습니다. 변경 될 때 두 파일에서 변경 될 것이라는 보장은 없습니다. 그것은 디버깅에 분명히 나쁘다.

또한 내일 정부에서 "5/3/2050부터 AUTHLDG-1A 대신 AUTHLDG-122B를 추가해야합니다"가 필요한 경우이 문자열 상수는 단순한 문자열 상수가 아닙니다. 아이디어를 나타내는 것입니다. 그것은 그 아이디어의 현재 가치 일뿐입니다 ( "원장이 500k 이상인 경우 추가하는 것").

명확히하겠습니다. 나는 그 기사가 잘못되었다고 말하는 것이 아니다. 나는 그것을 얻지 못한다. 어쩌면 (적어도 내 생각에는) 너무 잘 설명되어 있지 않을 수도 있습니다.

가능한 모든 문자열 리터럴 또는 숫자 값을 상수, 정의 또는 구성 변수로 바꾸는 것이 필요 할뿐만 아니라 지나치게 복잡하지만이 특정 예가이 범주에 속하지 않는 것으로 이해합니다. 나중에 필요하지 않다는 것을 어떻게 알 수 있습니까? 아니면 그 문제에 대해 다른 사람이 있습니까?


21
퍼즐을 틀어보십시오 : 그 숫자의 이름은 무엇입니까? 이름에 어떤 값도 추가하지 않거나 코드가 이미 설명하고 모호성 을 추가 하는 동안 종종 설명하는 모든 것을 설명한다고 생각합니다 ( "LedgerLimitForAuthDlg1A"?). 나는 이것이 얼마나 관련성이 있는지 정확하게 기사를 발견했다 . 두 가지 접근 방식을 모두 사용하는 시스템을 유지 관리했으며 비즈니스 규칙이 코드에 속한다고 말할 수 있습니다. 추적, 유지 관리 및 이해가 훨씬 쉽습니다. 구성을 사용하면 계산이 더 나아집니다. 훨씬 비쌉니다.
Luaan

2
구성해야 할 사항을 위해 구성을 예약해야합니다. 비즈니스 규칙을 일반적으로 구성 할 수없는 경우 약간만 구성하면 비즈니스 규칙을 사지 않아도됩니다.
biziclop

적절한 고급 언어의 경우 구성은 문자열이 아닌 실제 서브 루틴 형태를 취합니다.
Thorbjørn Ravn Andersen

답변:


100

저자는 조기 추상화에 대해 경고하고 있습니다.

이 선 if (ledgerAmt > 500000)은 요구 사항이 엄청나게 복잡하지만 정확하고 잘 문서화되어있는 복잡한 대규모 비즈니스 시스템에 대해 기대할 수있는 일종의 비즈니스 규칙처럼 보입니다.

일반적으로 이러한 종류의 요구 사항은 유용하게 재사용 가능한 논리가 아닌 예외적 / 가장 높은 경우입니다. 이러한 요구 사항은 일반적으로 엔지니어가 아닌 비즈니스 분석가 및 주제 전문가가 소유하고 유지 관리합니다.

(이러한 경우 비즈니스 분석가 / 전문가의 요구 사항에 대한 '소유권'은 일반적으로 전문가 분야의 개발자가 도메인 전문 지식이 충분하지 않은 경우에 발생하지만 개발자와 도메인 전문가 간의 완벽한 커뮤니케이션 / 협력을 통해 계속 보호 할 수 있습니다. 모호하거나 잘못 작성된 요구 사항.)

요구 사항이 엣지 케이스와 매우 복잡한 로직으로 가득 찬 시스템을 유지 관리 할 때는 일반적으로 해당 로직을 유용하게 추상화하거나보다 유지 관리하기 쉬운 방법이 없습니다. 추상화를 시도하면 쉽게 역효과를 낼 수 있습니다. 시간 낭비뿐만 아니라 유지 관리가 어려운 코드도 만들어집니다.

구성 파일 또는 #define, const 또는 언어가 제공하는 모든 것에서 값을 포함하는 것보다 그것을 어떻게 참조합니까? 나중에 프로그램이나 다른 프로그래머가 그 경계선을 필요로하므로 소프트웨어가 다른 선택을 할 수 있습니다. 변경 될 때 두 파일에서 변경 될 것이라는 보장은 없습니다. 그것은 디버깅에 분명히 나쁘다.

이러한 종류의 코드는 코드 자체가 요구 사항에 일대일로 매핑되어 있다는 사실에 의해 보호되는 경향이 있습니다. 개발자가 때 즉 알고 것을 500000그림은 요구 사항에 두 번 나타납니다, 그 개발자는 또한 코드에 두 번 나타나는 것을 알고있다.

500000요구 사항 문서의 여러 곳에 나타나는 다른 (동일하게) 시나리오를 고려 하지만 주제 전문가는 그 중 하나만 변경하기로 결정합니다. 거기에서 const가치를 바꾸는 누군가 500000가 다른 것을 의미한다는 것을 깨닫지 못할 수도 있는 더 나쁜 위험이 있습니다. 따라서 개발자는 하나를 변경하고 코드에서 찾은 곳에서만 코드를 찾은 다음 무언가를 깨뜨립니다. 그들이 바뀌 었다는 것을 몰랐다.

이 시나리오는 맞춤형 법률 / 재정 소프트웨어 (예 : 보험 견적 논리)에서 많이 발생합니다. 이러한 문서를 작성하는 사람은 엔지니어가 아니며 스펙의 전체 덩어리를 복사하여 붙여 넣기, 몇 단어 / 숫자를 수정하는 데 문제가 없습니다. 대부분을 동일하게 유지합니다.

이러한 시나리오에서 복사 붙여 넣기 요구 사항을 처리하는 가장 좋은 방법은 복사 붙여 넣기 코드를 작성하고 코드가 가능한 모든 요구 사항 (모든 데이터 하드 코딩 포함)과 비슷하게 보이도록하는 것입니다.

이러한 요구 사항의 현실은 일반적으로 오랫동안 복사 + 붙여 넣기 상태를 유지하지 않고 값이 정기적으로 변경되는 경우가 종종 있지만 동시에 변경되지 않으므로 요구 사항을 합리화하거나 추상화하려고합니다. 어떤 식 으로든 요구 사항을 코드로 변환하는 것보다 더 많은 유지 관리 문제가 발생합니다.


28
DSL (Domain Specific Language)은 코드를 요구 사항 문서와 같이 더 많이 읽을 수있는 좋은 방법입니다.
Ian

13
DSL의 또 다른 장점은 실수로 응용 프로그램, 프레젠테이션 또는 지속성 논리를 비즈니스 규칙과 혼합하기가 더 어렵다는 것입니다.
Erik Eidt

16
애플리케이션이 자체 DSL을 보증 할만큼 특별하다고 생각하는 것이 일반적 입니다.
brian_o

8
Those requirements are typically owned and maintained by business analysts and subject matter experts, rather than by engineers항상 좋은 생각은 아닙니다. 때로는 이러한 요구 사항을 코드로 전환하는 행위로 인해 요구 사항이 잘 정의되지 않았거나 비즈니스 관심사와 상충되는 방식으로 정의되는 경우가 드러날 수 있습니다. 비즈니스 분석가와 개발자가 공통의 목표를 달성하기 위해 협력 할 수 있다면 많은 문제를 피할 수 있습니다.
kasperd

4
@ BenCottrell 나는 소프트웨어를보다 쉽게 ​​작성할 수 있도록 규칙을 바꾸라고 제안하지 않았다. 그러나 규칙에 많은 조건이있는 경우 규칙을 처음 정의 할 때 이들 사이의 일부 상호 작용이 누락되었을 수 있습니다. 그러나 스펙을 코드로 바꾸면 개발자는 이러한 조건간에 상호 작용이있을 수 있음을 알아야합니다. 이 시점에서 개발자는 사양에 대한 엄격한 해석이 고객이 시스템을 게임 할 수있게하는 의도하지 않은 가격으로 이어진다는 것을 알게 될 수 있습니다.
kasperd

44

이 기사에는 좋은 지적이있다. 구성 파일에 상수를 추출하는 것은 어떻게 나쁜 습관이 될 수 있습니까? 불필요하게 코드를 복잡하게하면 나쁜 습관이 될 수 있습니다. 코드에 직접 값을 갖는 것은 구성 파일에서 값을 읽는 것보다 훨씬 간단하며 작성된 코드를 쉽게 따라갈 수 있습니다.

또한 내일 정부는 "5/3/2050부터 AUTHLDG-1A 대신 AUTHLDG-122B를 추가해야합니다"로갑니다.

그래, 그럼 코드를 바꿔 이 기사의 요점은 구성 파일을 변경하는 것보다 코드를 변경하는 것이 더 복잡하지 않다는 것입니다.

이 기사에서 설명하는 접근 방식은 더 복잡한 논리를 얻는 경우 확장되지 않지만 요점은 판단을 내려야하며 때로는 가장 간단한 솔루션이 가장 좋습니다.

나중에 필요하지 않다는 것을 어떻게 알 수 있습니까? 아니면 그 문제에 대해 다른 사람이 있습니까?

이것이 YAGNI 원칙의 요점입니다. 알려지지 않은 미래를 위해 설계하지 마십시오. 현재에는 완전히 다른 디자인이 될 수 있습니다. 500000 값을 프로그램의 여러 위치에서 사용 하는 경우 물론 상수로 추출해야합니다. 그러나 문제의 코드에서는 그렇지 않습니다.

소프트 코딩은 실제로 우려분리 문제 입니다. 알고 있는 정보 는 핵심 응용 프로그램 논리와 독립적 으로 변경 될 수 있습니다 . 응용 프로그램 논리와는 독립적으로 변경 될 수 있다는 점을 알고 있으므로 다른 환경에 따라 연결 문자열을 구분해야하기 때문에 연결 문자열을 데이터베이스에 하드 코딩하지 마십시오. 웹 앱에서는 비즈니스 로직을 html 템플릿 및 스타일 시트와 분리하려고합니다. 개별적으로 변경 될 수도 있고 다른 사람에 의해 변경 될 수도 있기 때문입니다.

그러나 코드 샘플의 경우 하드 코딩 된 문자열과 숫자는 응용 프로그램 논리의 필수 부분입니다. 제어 외부의 일부 정책 변경으로 인해 하나의 파일 이름이 변경 될 수 있지만 다른 조건에 대해 새 if-branch 검사를 추가해야합니다. 이 경우 파일 이름과 숫자를 추출하면 실제로 응집력이 손상됩니다.


4
종종 구성 파일보다 코드를 변경하는 것이 훨씬 더 복잡합니다. 전자의 경우 개발자와 빌드 시스템 / 릴리스주기가 필요할 수 있지만 후자는 친숙한 구성 UI의 상자에서 숫자 만 변경하면됩니다.
OrangeDog

6
@OrangeDog 그래, 처음 보는 방법이야. 이 같은 일을 할 경우 단, 구성 UI 아무것도 될 것입니다 하지만 무엇을 알고 누구인지를 묻는 완전히 의미가 텍스트 상자 수백, 친절. 이제 UI를 빌드하고 문서화해야합니다. 구성이 결코 좋은 방법이 아니라는 것을 의미하지는 않습니다. 절대적으로 올바른 선택입니다. 그러나 기사의 어떤에서도 아닙니다 . 그리고 법안이 단지 숫자를 바꾼 마지막 시간은 언제입니까? 부가가치세 규칙이 마지막으로 변경된 시점에서 모든 계산을 다시 수행해야했습니다.
Luaan

2
@OrangeDog : 여기서 소프트웨어의 구성은 확인에 필요한 후크를 제공한다고 가정합니다. OP에서 각각 if이 다른 변수를 기반으로하는 방법에 유의하십시오 ! 구성에서 필요한 변수에 액세스 할 수 없으면 소프트웨어를 수정해야합니다.
Matthieu M.

2
@OrangeDog 그래서 개발자 / QA / 릴리스주기와 적절한 테스트없이 소프트웨어 응용 프로그램 의 논리 가 크게 변경되어야한다고 제안하고 있습니까?
NPSF3000

3
@OrangeDog : 예에서 논리를 구성하기 위해 YAML을 사용합니다. 논리에는 조건부 규칙이 포함되어 있으므로 YAML에서 이러한 조건을 나타내는 방법을 찾을 수 있습니다. 축하합니다. 파이썬을 재창조하셨습니다. 그렇다면 전체 앱을 파이썬으로 작성하지 않겠습니까?
JacquesB

26

이 기사에서는 '엔터프라이즈 규칙 엔진'에 대해 이야기하고 있으며, 이는 아마도 그가 주장하는 것에 대한 더 나은 예일 것입니다.

논리는 구성이 너무 복잡하여 자체 프로그래밍 언어를 포함하는 지점으로 일반화 할 수 있다는 것입니다.

예를 들어, 예제에서 상태 코드 대 문서 맵핑은 구성 파일로 이동 될 수 있습니다. 그러나 복잡한 관계를 표현해야합니다.

<statecode id="AZ">
    <document id="SR008-04X"/>
    <document id="SR008-04XI"/>
</statecode>

원장 금액을 넣을 수도 있습니까?

<statecode id="ALL">
    <document id="AUTHLDG-1A" rule="ledgerAmt >= 50000"/>
</statecode>

곧 새로운 언어로 프로그래밍하고 소스 또는 변경 제어가없는 구성 파일에 해당 코드를 저장하고 있음을 알게되었습니다.

이 기사는 이런 종류의 일이 일반적인 접근 방식 인 2007 년에 작성된 것입니다.

요즘 우리는 의존성 주입 (DI) 문제를 해결할 것입니다 . 즉, '하드 코딩 된'

InvoiceRules_America2007 : InvoiceRules

하드 코딩되거나 더 구성 가능한 것으로 대체 할 것입니다.

InvoiceRules_America2008 : InvoiceRules

법률 또는 비즈니스 요구 사항이 변경된 경우


4
아마도 "DI"를 정의해야합니다. 그리고 좀 더 설명해주세요.
Basil Bourque

9
해당 파일이 소스 제어 시스템에없는 이유는 무엇입니까?
JDługosz

2
클라이언트 if마다 다르면 코딩 된 버전 에 각 클라이언트에 대해 다른 값을 제공 하는 명령문이 엉망 입니까? 구성 파일에 있어야하는 것 같습니다 . 한 종류의 파일에 있거나 다른 모든 파일이 동일한 것은 파일을 제어 / 추적 / 백업하지 않는 이유가 아닙니다. @ewan는 DSL의 파일을 이미지와 사운드 파일과 문서 등도 아닌 코드 자산 확실히 어떤 이유로 프로젝트의 일부로 저장 될 수 없음을 말하는 것 입니다 .
JDługosz

2
XML에서 "50000"값을 리팩터링하여 별도의 구성 파일에 넣어야한다고 생각하지 않습니까? 그건 그렇고 500000이어야합니다.
와일드 카드

1
@jdlugosz ERE의 개념은 시스템을 구입 한 다음 필요에 따라 구성하는 것입니다. 아마도 내부 개발자들이이 '유연한'시스템과 경쟁했기 때문에 아마도 그것들을 모방하려고 시도했을 것입니다. IBM과 같은 대기업의 시스템에서도 구성 변경 제어가 종종 고려되었습니다. 판매 포인트는 빠른 변화였다
Ewan

17

반대로 "500000"은 단순한 숫자가 아닙니다. 기능의 중단 점에 대한 아이디어를 나타내는 중요한 가치입니다. 이 숫자는 여러 곳에서 사용될 수 있지만 사용하고있는 숫자가 아니라 한계 / 경계선에 대한 아이디어로, 어떤 규칙이 적용되고 어떤 규칙이 적용되는지가 결정됩니다.

그리고 그것은 다음과 같이 표현됩니다 (그리고 의견조차도 중복 적이라고 주장 할 수 있습니다).

 if (ledgerAmnt >= 500000) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
  }

이것은 코드가하는 일을 반복합니다.

LEDGER_AMOUNT_REQUIRING_AUTHLDG1A=500000
if (ledgerAmnt >= LEDGER_AMOUNT_REQUIRING_AUTHLDG1A) {
    //Ledger of 500K or more requires AUTHLDG-1A
    attachDocument("AUTHLDG-1A");
}

저자는 500000의 의미가이 규칙과 관련이 있다고 가정합니다. 다른 곳에서 재사용되거나 재사용 될 수있는 값이 아닙니다.

이 이전 소프트 코딩에서 고려할 수있는 유일한 비즈니스 규칙 변경은 AUTHLDG-1A 양식이 필요한 원장 금액의 변경입니다. 다른 비즈니스 규칙을 변경하려면 구성, 문서, 코드 등 더 많은 작업이 필요합니다.

필자의 관점에서 기사의 요점은 때로는 숫자가 단지 숫자라는 것입니다. 코드에서 전달되는 내용 외에 다른 의미로는 사용되지 않을 것이라는 추가 의미는 없습니다. 따라서 하드 코딩 된 값을 피하기 위해 변수 이름에서 코드가 현재 수행중인 작업을 어색하게 요약하는 것은 전혀 불필요한 반복입니다.


2
constant를 도입하면 LEDGER_AMOUNT_REQUIRING_AUTHLDG1A더 이상 주석을 코드에 쓰지 않습니다. 프로그래머는 주석을 잘 관리하지 못합니다. 금액이 변경된 경우 if조건과 설명이 동기화되지 않습니다. 반대로 상수는 LEDGER_AMOUNT_REQUIRING_AUTHLDG1A절대 자신과 동기화되지 않으며 불필요한 설명없이 목적을 설명합니다.
ZeroOne

2
@ZeroOne : 비즈니스 규칙이 "500K 이상의 대가로 AUTHLDG-1A 및 AUTHLDG-2B가 필요함"으로 변경되는 경우, attachDocument("AUTHLDG-2B");회선 을 추가 한 사람 이 상수 이름을 동시에 업데이트하지 못할 가능성이 큽니다 . 이 경우, 나는 코드가 충분히 매우 분명하다 생각 코멘트 설명자 변수. (이 적합 할 수 있습니다 있지만 코드 주석을 통해 비즈니스 요구 사항 문서의 해당 섹션을 지시하는 규칙을 가지고하는 그런 대회, 수행하는 코드 주석에서. 여기에 해당 될 것입니다.)
ruakh

@ruakh, OK, 그리고 호출 할 상수를 리팩터링합니다 LEDGER_AMOUNT_REQUIRING_ADDITIONAL_DOCUMENTS(아마도 처음에해야했을 것입니다). 또한 비즈니스 요구 사항 ID를 소스 코드가 아닌 Git 커밋 메시지에 넣는 습관이 있습니다.
ZeroOne

1
@ZeroOne : 그러나 AUTHLDG-3C의 경우 원장 금액은 실제로 최대 입니다. AUTHLDG-4D의 경우 적절한 원장 금액은 주에 따라 다릅니다. (아직 요점을 알고 있습니까?이 유형의 코드의 경우 비즈니스 규칙의 진화가 비즈니스 규칙의 진화와 일치 할 것으로 기대할 이유가 없으므로 비즈니스 규칙의 추상화 시도가 아닌 비즈니스 규칙을 코드에 반영하기를 원합니다. 당신이 채택한 추상화.)
ruakh

2
개인적으로, 나는 마법 번호를 코드에 넣는 것에 반대하지 않고 코드를 구성하는 것에 반대하므로 주석이 필요합니다. 그것이 나이라면, 각 문서를 자체 attachIfNecessary()메소드를 사용하여 열거 형 인스턴스로 만들고 모든 문서를 반복합니다.
David Moles

8

다른 답변은 정확하고 신중합니다. 그러나 여기에 짧고 달콤한 대답이 있습니다.

  Rule/value          |      At Runtime, rule/value…
  appears in code:    |   …Is fixed          …Changes
----------------------|------------------------------------
                      |                 |
  Once                |   Hard-code     |   Externalize
                      |                 |   (soft-code)
                      |                 |
                      |------------------------------------
                      |                 |
  More than once      |   Soft-code     |   Externalize
                      |   (internal)    |   (soft-code)
                      |                 |
                      |------------------------------------

규칙과 특수 값이 코드의 한 곳에 나타나고 런타임 중에 변경되지 않으면 질문에 표시된대로 하드 코딩하십시오.

규칙 또는 특수 값이 코드에서 둘 이상의 위치에 나타나고 런타임 중에 변경되지 않으면 소프트 코드입니다. 규칙에 대한 소프트 코딩으로 특정 클래스 / 방법을 정의하거나 빌더 패턴을 사용할 수 있습니다 . 값의 경우 소프트 코딩은 코드 전체에서 사용되는 단일 상수 또는 열거 형을 정의하는 것을 의미 할 수 있습니다.

런타임 동안 규칙 또는 특수 값이 변경 될 수 있으면이를 외부화해야합니다. 일반적으로 데이터베이스의 값을 업데이트하여 수행됩니다. 또는 사용자가 데이터를 입력하여 메모리의 값을 수동으로 업데이트하십시오. 또한 파일 수정 날짜-시간 변경을 위해 반복적으로 스캔되는 텍스트 파일 (XML, JSON, 일반 텍스트 등)에 값을 저장하여 수행됩니다.


1
귀하의 답변이 마음에 들지만 구현시 변경되는지 여부도 고려해야한다고 생각합니다. 예를 들어 감독
당국이

이 답변과 구현에 대한 의견 모두에 동의했습니다. 내가 작업하는 것들은 많은 조직에 의해 구현되며, 많은 것들은 미묘하게 다른 가치가 필요합니다. 우리는 이러한 '설정'을 구성 파일이 아닌 데이터베이스에 저장하는 경향이 있지만 원칙적으로 소프트웨어를 구현하는 회사마다 소프트웨어 빌드를 다르게하고 싶지 않습니다 (그런 다음 업그레이드 할 때마다 다른 빌드를 반복 함) .
RosieC

7

이것은 우리가 사용하는 경우에 우리가 가을 함정 장난감 문제를 다음에만 포즈 strawman의 우리가 실제 문제를 설명하려고 할 때, 솔루션을.

주어진 예에서, 주어진 값이 인라인 값으로 하드 코딩되거나 const로 정의되는지의 차이는 없습니다.

예제를 유지 관리 및 코딩 공포로 만드는 것은 주변 코드입니다. 이 경우 없습니다 에는 주변 코드는 다음 코드 조각은 적어도 일정 리팩토링의 환경에서, 괜찮습니다. 리팩토링이 발생하지 않는 환경에서, 해당 코드의 관리자는 이미 명백해지기 때문에 이미 죽었습니다.

주변에 코드가 있으면 나쁜 일이 분명히 발생합니다.

첫 번째 나쁜 점은 50000 값이 일부 주에서 세율이 변하는 원장 금액과 같은 다른 값에 사용된다는 것입니다. 그런 다음 변경이 발생하면 관리자는 알 수 없습니다. 코드에서 50000의 두 인스턴스 (동일한 50k를 의미하는지 또는 전혀 관련이없는 50ks)를 의미합니다. 누군가가 상수를 사용하는 경우 49999 및 50001도 검색해야합니까? 이것은 별도의 서비스의 구성 파일에 변수를 넣는 호출이 아니지만 인라인 하드 코딩도 잘못되었습니다. 대신, 사용되는 클래스 나 파일 내에서 정의되고 범위가 지정된 상수 여야합니다. 50k의 두 인스턴스가 동일한 상수를 사용하는 경우 동일한 입법 제한을 나타냅니다. 그렇지 않다면 아마 그렇지 않을 것입니다. 어느 쪽이든, 그들은 이름을 가질 것입니다.

파일 이름은 기본 파일 이름을 경로 또는 확장자없이 문자열로 허용하는 attachDocument () 함수에 전달됩니다. 파일 이름은 기본적으로 일부 파일 시스템 또는 데이터베이스에 대한 외래 키이거나 attachDocument ()가 파일을 가져 오는 곳입니다. 그러나 문자열은 이것에 대해 아무 것도 말하지 않습니다. 몇 개의 파일이 있습니까? 어떤 유형의 파일입니까? 새로운 시장에 진입 할 때이 기능을 업데이트해야하는지 어떻게 알 수 있습니까? 어떤 유형의 물건을 붙일 수 있습니까? 관리자는 완전히 어둠 속에 남겨져 있으며, 코드에 여러 번 나타날 수있는 문자열 일뿐입니다. 한 곳에서 "SR008-04X"는 치트 코드입니다. 또 다른 방법으로, 4 개의 SR008 부스터 로켓을 주문하라는 명령입니다. 여기 요 sa 파일 이름? 이것들이 관련이 있습니까? 누군가 "CLIENT"라는 다른 파일을 언급하기 위해 해당 기능을 변경했습니다. 그런 다음 유지 관리에 문제가있는 사용자는 "CLIENT"파일의 이름을 "CUSTOMER"로 바꿔야한다는 메시지를 받았습니다. 그러나 문자열 "CLIENT"는 코드에서 937 번 나타납니다. 어디서부터 시작합니까?

장난감 문제는 값이 모두 특이하고 합리적으로 코드에서 고유 보장 할 수 있다는 것입니다. "1"또는 "10"이 아니라 "50,000"입니다. "클라이언트"또는 "보고서"가 아니라 "SR008-04X"입니다.

strawman는 impenetrably 불투명 상수의 문제를 해결하는 유일한 방법은 어떤 관련이없는 서비스의 config 파일에 그들을 하이브하는 것입니다.

이 두 가지 오류를 함께 사용하면 모든 주장이 사실임을 입증 할 수 있습니다.


2
장난감 문제가 아니라 밀짚 꾼이 ​​아닙니다. 이것은 이런 종류의 비즈니스 응용 프로그램에서 항상 볼 수있는 것 입니다. "새로운 시장을 개척"할 수 없으며, 같은 수를 재사용 할 수 없으며 (결국 어쨌든 다른 의미를 부여 할 것입니다) 어쨌든 기사는 DRY에 대해 아무 말도하지 않습니다. 가치에 두 가지의 의존성이 있다면 메소드 또는 상수로 이동합니다. 구성 설정의 상수가 실제로 어떻게 중요하지 않은지, 그리고 미래의 증거이며 코드보다 명확한 방식으로 저장해야하는 위치의 예를 보여줍니다.
Luaan

4
장난감 문제이기 때문에 예제가 손상되지 않습니다. 소프트웨어가 실행해야하는 비즈니스 규칙이 끔찍하기 때문에 주변 코드는 항상 끔찍 합니다 . 시도는 규칙 엔진과 DSL을이 근본적인 도전을 단계 측과 이것 저것 자주하는 프로그래머 꾸물 거리는 CS 문제를 해결하는 것은 세금 양식의 복잡성을 해결하는 것보다 더 즐거운 때문에. 소프트웨어의 궁극적 인 임무는 복잡한 재난을 모델링하는 것이기 때문에 '우아함'을 달성하려는 시도는 종종 바보의 심부름입니다.
whatsisname

비즈니스 규칙은 공포가 될 수 있지만, 그 자체로는 이런 종류의 평범한 절차 코드를 작성하는 데 대한 변명이 아닙니다. (나는 구성보다 코드에서 규칙을 모델링하고 유지하는 것이 더 쉽다는 Papadimoulis에 동의하는 경향이있다. 나는 그것이 더 나은 코드라고 생각한다.) 내가 본 DRY 문제는 마법의 숫자가 아니라 반복된다는 것이다 if (...) { attachDocument(...); }.
David Moles

2

여기에는 몇 가지 문제가 있습니다.

한 가지 문제는 모든 규칙을 프로그램 외부에서 쉽게 구성 할 수 있도록 규칙 엔진을 구축해야한다는 것입니다. 이와 비슷한 경우의 대답은 가장 자주 없습니다. 규칙은 예측하기 어려운 이상한 방식으로 변경되므로 변경이있을 때마다 규칙 엔진을 확장해야합니다.

또 다른 문제는 버전 관리에서 이러한 규칙과 변경 사항을 처리하는 방법입니다. 여기서 가장 좋은 해결책은 규칙을 각 규칙의 클래스로 나누는 것입니다.

이를 통해 각 규칙마다 고유 한 유효성을 유지하고, 일부 규칙은 매년 변경되며, 허가가 있거나 송장이 발행 될 때 변경되는 일부 변경 사항이 있습니다. 적용 할 버전 확인이 포함 된 규칙 자체입니다.

또한 상수는 개인이므로 코드의 다른 곳에서는 잘못 사용할 수 없습니다.

그런 다음 모든 규칙 목록을 작성하고 목록을 적용하십시오.

추가 문제는 상수를 처리하는 방법입니다. 500000은 눈에 띄지 않을 수 있지만 올바르게 변환되도록 매우주의해야합니다. 부동 소수점 산술을 적용하면 500,000.00001로 변환되어 500,000.00000과의 비교에 실패 할 수 있습니다. 또는 더 나쁜 500000은 항상 의도 한대로 작동하지만 변환시 565000이 실패합니다. 컴파일러가 추측하는 것이 아니라 명시 적으로 변환해야합니다. 종종 사용하기 전에 BigInteger 또는 BigDecimal로 변환하여 수행됩니다.


2

질문에 직접 언급되지는 않지만 중요한 것은 비즈니스 로직을 코드 에 묻지 않는 것 입니다.

위의 예와 같이 외부에서 지정한 비즈니스 요구 사항 을 인코딩 하는 코드 는 실제로 소스 트리의 특정 부분 (예 : 이름이 businesslogic있거나 이와 유사한 것)에 존재해야하며 코드를 확실히 유지해야합니다. 비즈니스 요구 사항을 단순하고 읽기 쉬운 방식으로 인코딩 최소한의 상용구와 명확하고 유익한 의견으로 가능한 간결하게.

비즈니스 로직을 수행하는 데 필요한 기능 을 구현 하는 "인프라"코드와 혼용 해서는 안됩니다 .attachDocument() 예 : 예제 메소드 또는 일반적으로 UI, 로깅 또는 데이터베이스 코드) . 이러한 분리를 시행 하는 한 가지 방법은 구성 파일에있는 모든 비즈니스 논리를 "소프트 코드" 하는 것이지만 유일한 방법은 아닙니다.

이러한 비즈니스 논리 코드는 코딩 기술이없는 비즈니스 도메인 전문가에게 보여 주면 코드를 이해할 수있을 정도로 명확하게 작성해야합니다. 최소한 비즈니스 요구 사항이 변경 될 경우이를 인코딩하는 코드는 코드베이스에 대한 사전 지식이없는 새로운 프로그래머라도 비즈니스 로직을 쉽게 찾고 검토하고 업데이트 할 수있을 정도로 명확해야합니다. 질적으로 새로운 기능이 필요하지 않습니다.

이상적으로, 이러한 코드는 비즈니스 로직과 기본 인프라 간의 분리를 강제하기 위해 도메인 별 언어로 작성되지만 기본 사내 앱에는 불필요하게 복잡 할 수 있습니다. 즉, 각각 고유 한 사용자 지정 비즈니스 규칙 집합이 필요한 여러 클라이언트에 소프트웨어를 판매하는 경우 간단한 도메인 별 스크립팅 언어 (예 : Lua 샌드 박스 기반 )가 문제 일 수 있습니다.


이것이 바로 내가 생각한 것입니다 !!! 논리가 코드에 깊이 묻혀있을 때 도메인 / 대상 전문가 또는 비즈니스 사용자는 올바른지 확인하고 시스템 동작을 진단하기 위해 사용중인 값과 논리를 어떻게 볼 수 있습니까? 설정 파일이하는 한 가지는 설정을 보이게하는 것 입니다. 코딩이 "어려워"지는 경우에도 비즈니스 규칙의 가시성을 높이는 몇 가지 수단이 필요합니다. 비즈니스 사용자가 액세스하고 이해할 수있는 수단이 있다면 다른 관심사와 혼동하지 않고 업무를 수행하는 얇은 클래스 또는 클래스 세트를 승인 할 수 있습니다.
ErikE
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.