절대 변경되지 않는 하드 코딩 문자열


39

그래서 프랑스어로 동사를 (공 법적으로, 데이터 세트를 통하지 않고) 켤 수있는 프로그램을 작성하려는 노력에서 약간의 문제가 발생했습니다.

동사를 켤 수있는 알고리즘은 실제로 17 개 또는 17 개의 동사에 대해 상당히 단순하며 각 경우에 특정 패턴으로 실행됩니다. 따라서이 17 개의 클래스에 대한 접합 접미사는 정적이며 조만간 변경되지 않을 것입니다. 예를 들면 다음과 같습니다.

// Verbs #1 : (model: "chanter")
    terminations = {
        ind_imp: ["ais", "ais", "ait", "ions", "iez", "aient"],
        ind_pre: ["e", "es", "e", "ons", "ez", "ent"],
        ind_fut: ["erai", "eras", "era", "erons", "erez", "eront"],
        participle: ["é", "ant"]
    };

이것들은 프랑스어에서 가장 일반적인 동사 부류에 사용되는 접미사입니다.

동사의 다른 종류의 동사 (불규칙한 형태)가 있는데, 그 동사의 활용은 다음 세기 나 2 세기 동안 정적으로 유지 될 가능성이 매우 높다. 그것들은 불규칙적이기 때문에, 완전한 컨쥬 게이션은 정적으로 포함되어야한다. 그것들은 패턴으로부터 확실하게 결합 될 수 없기 때문이다 (또한 내 카운트에 의해 32 개의 불규칙 만이 존재한다). 예를 들면 다음과 같습니다.

// "être":
    forms = {
        ind_imp: ["étais", "étais", "était", "étions", "étiez", "étaient"],
        ind_pre: ["suis", "es", "est", "sommes", "êtes", "sont"],
        ind_fut: ["serai", "seras", "sera", "serons", "serez", "seront"],
        participle: ["été", "étant"]
    };

이 모든 것을 XML이나 JSON에 넣고 사용해야 할 때 직렬화를 해제 할 수는 있지만 요점이 있습니까? 이 줄은 자연어의 일부이며 변경되는 속도는 느립니다.

내 관심사는 "올바른"방식으로 작업하고 일부 데이터 소스를 역 직렬화 함으로써 복잡 하지 않아도 되는 문제를 복잡하게 만들었을뿐 아니라 알고리즘 접근 방식 : 데이터 소스를 사용 하지 않는 것! C #에서는 namespace Verb.Conjugation(예를 들어 class Irregular) 아래에 이러한 문자열을 XML로 채우고을 만드는 대신 열거 된 유형 또는 무언가로 저장할 클래스를 만들 수 있습니다 class IrregularVerbDeserializer.

질문 : 그럼 그것은 하드 코드 문자열에 적합한 매우 응용 프로그램의 수명 동안 변화 가능성? 물론 100 %가 변하지 않을 것이라고 보장 할 수 는 없지만 위험 대 비용은 거의 눈에 띄지 않습니다. 하드 코딩이 더 좋습니다.

편집 : 제안 된 복제본많은 수의 정적 문자열을 저장하는 방법을 묻지 만 제 질문은 언제 정적 문자열을 하드 코딩 해야하는지 입니다.


26
나중에 프랑스어 이외의 다른 언어로이 소프트웨어를 사용하고 싶습니까?

10
알고리즘 접근법이든 아니든간에, 단순히 32 * 20 문자열을 하드 코딩해야하며 더 많은 언어를 추가 할 때 더 많은 코드를 작성해야하며 유일한 실제 질문은 어디에 넣을 것인가입니다. 나는 당신에게 가장 편리한 곳을 선택합니다. 당분간 코드에있는 것처럼 들립니다. 나중에 언제든지 섞을 수 있습니다.
Ixrec

1
@ChrisCirefice 저에게 거의 최적 인 것 같습니다. 해봐
Ixrec

2
@Gusdor 나는 당신이 명확하게 읽는다고 생각하지 않습니다-나는 활용 패턴 이 결코 변하지 않을 것이라고 말했다. 물론 코드는 변경되지만 리팩토링하지 않는 한 문자열이 원하는 방식으로 거기에 있으면 향후 100 년 동안 정적 상태가됩니다.
크리스 Cirefice

1
+1. 60-100 년 안에 비용이 존재하지 않거나 더 나은 버전으로 대체되었다는 것은 말할 것도 없습니다.
HarryCBurn

답변:


56

응용 프로그램 수명 동안 변경되지 않는 문자열을 하드 코딩하는 것이 적절합니까? 물론 100 %가 변하지 않을 것이라고 보장 할 수는 없지만 위험 대 비용은 거의 눈에 무게를 tri 수 없습니다. 하드 코딩이 더 좋습니다.

당신이 당신의 자신의 질문에 대답 한 것으로 보입니다.

우리가 겪는 가장 큰 어려움 중 하나는 변하지 않는 물건과 변하지 않는 물건을 분리하는 것입니다. 어떤 사람들은 견딜 수 있고 구성 파일에 할 수있는 모든 것을 완전히 버립니다. 다른 사람들은 다른 극단으로 가서 가장 명백한 변화조차도 다시 컴파일해야합니다.

더 복잡하게 만드는 강력한 이유를 찾을 때까지 가장 쉬운 방법으로 구현했습니다.


고마워 댄, 내가 생각한 것 같아 이를 위해 XML 스키마를 작성하고, 추적 할 다른 파일이 있고, 데이터를 직렬화 해제하기위한 인터페이스를 작성해야하는 것은 문자열이 많지 않다는 점을 고려할 때 과도하게 보였다. 앞으로 100 년 안에 운 좋게도 오늘날 프로그래밍 언어에서는이 원시 데이터를 멋진 인터페이스 뒤에 추상화하는 멋진 방법 French.Verb.Irregular.Etre이 있습니다. 예를 들어 내 질문의 데이터가 포함됩니다. 나는 확실히 밖으로 작동 생각)
크리스 Cirefice

3
+1 여기 Ruby 캠프에서 하드 코딩을 시작하고 필요에 따라 구성으로 옮깁니다. 구성 할 수있게하여 프로젝트를 너무 과도하게 엔지니어링하지 마십시오. 속도가 느려집니다.
Overbryd

2
참고 : 일부 그룹은 "하드 코딩"의 정의가 다르므로 해당 용어는 여러 가지를 의미합니다. ( if (num == 0xFFD8)) 와 같이 데이터 구조를 작성하지 않고 함수의 명령문에 값을 하드 코딩하는 잘 알려진 안티 패턴이 있습니다 . 이 예제는 if (num == JPEG_MAGIC_NUMBER)가독성을 위해 거의 모든 경우 와 비슷해야합니다 . "하드 코딩"이라는 단어가 종종 단어의 다른 의미로 인해 사람들의 목에 머리카락을 내기 때문에 지적합니다.
Cort Ammon 2016 년

@CortAmmon JPEG에는 많은 매직 넘버가 있습니다. 확실히 JPEG_START_OF_IMAGE_MARKER?
user253751

@immibis 일정한 이름의 선택은 아마도 내 것보다 낫습니다.
Cort Ammon

25

잘못된 범위를 추론하고 있습니다.

개별 동사 만 하드 코딩하지 않았습니다. 언어 와 해당 규칙 을 하드 코드했습니다 . 이는 애플리케이션을 다른 언어로 사용할 수 없으며 다른 규칙으로 확장 할 수 없음을 의미합니다.

이것이 당신의 의도라면 (즉, 프랑스어로만 사용), 이것은 YAGNI 때문에 올바른 접근법입니다. 그러나 나중에 다른 언어에서도 사용하고 싶다는 것을 인정합니다. 곧 곧 모든 하드 코딩 된 부분을 구성 파일로 이동해야합니다. 나머지 질문은 다음과 같습니다.

  • 가까운 시일 내에 100 %에 가까운 확실성으로 앱을 다른 언어로 확장 하시겠습니까? 그렇다면 앱의 주요 부분을 다시 작성하지 말고 JSON 또는 XML 파일 (단어, 단어의 일부 등) 및 동적 언어 (규칙의 경우)로 항목을 내 보내야합니다.

  • 또는 향후 어딘가에 앱이 확장 될 가능성은 아주 적습니다.이 경우 YAGNI는 가장 간단한 방법 (현재 사용중인 방법)이 더 낫다고 지시합니까?

예를 들어, Microsoft Word의 맞춤법 검사기를 사용하십시오. 하드 코딩 된 것으로 생각되는 것이 몇 개입니까?

텍스트 프로세서를 개발하는 경우 하드 코드 규칙 및 하드 코드 단어가 포함 된 간단한 맞춤법 엔진으로 시작할 수 if word == "musik": suggestSpelling("music");있습니다. 빠르게 단어를 옮기기 시작한 다음 코드 외부에서 스스로 규칙을 정하십시오. 그렇지 않으면:

  • 단어를 추가해야 할 때마다 다시 컴파일해야합니다.
  • 새로운 규칙을 배운 경우 소스 코드를 다시 한 번 변경해야합니다.
  • 더 중요한 것은 엄청난 양의 코드를 작성하지 않고 엔진을 독일어 나 일본어로 조정할 수있는 방법이 없다는 것입니다.

자신을 강조한대로 :

프랑스어 규칙은 일본어에 거의 적용되지 않습니다.

언어 규칙을 하드 코딩하는 즉시, 특히 자연 언어의 복잡성을 고려할 때 다른 언어마다 더 많은 코드가 필요합니다.

또 다른 주제는 코드를 통하지 않고 다른 규칙을 표현하는 방법입니다. 궁극적으로 프로그래밍 언어 가장 적합한 도구 라는 것을 알게 될 것 입니다. 이 경우 엔진을 다시 컴파일하지 않고 확장해야하는 경우 동적 언어 가 좋은 대안이 될 수 있습니다.


1
물론 모든 것이 하드 코딩 된 것은 아닙니다 : P 그래서 인터페이스가 어떤 언어를 원하는지 결정하여 여러 언어에 적용 할 수 있다고 생각합니다. 문제는 아직 모든 언어를 충분히 알지 못하기 때문에 사실상 불가능합니다. 어쩌면 당신이 빠뜨릴 있는 한 가지 생각은 컨쥬 게이션 패턴 (이것이 내가 말하는 전부)이 언어에서 매우 정적이며, 실제로는 사례마다 다른 것입니다. 동사에는 프랑스어로 약 17 개의 활용 패턴이 있습니다. 그것은 곧 확장되지 않을 것입니다 ...
크리스 Cirefice

4
나는 동의하지 않는다-리팩토링을 통해 자연스럽게 코드가 나오기 전에 코드 외부로 무언가를 옮기는 것이 합리적이라고 생각하지 않는다. 한 언어로 시작하고 다른 언어를 추가하십시오. ILanguageRule의 구현은 XML (또는 다른 파일)로 단일 구현을 매개 변수화하는 것이 더 효율적인 충분한 코드를 공유합니다. 그러나 그때조차도 완전히 다른 구조의 일본어로 끝날 수 있습니다. 인터페이스를 XML (또는 이와 유사한)로 밀어서 시작하는 것은 구현이 아니라 인터페이스를 변경하는 것만 요구합니다.
ptyx

2
참고 : 언어를 더 추가하려는 경우 언어를 구성 파일로 이동하는 것은 아닙니다. LanguageProcessor여러 서브 클래스 가있는 클래스를 동등하게 가질 수 있습니다. (효과적으로은 "설정 파일은"실제로 클래스)
user253751

2
@MainMa : 단어를 추가 할 때 왜 재 컴파일해야한다고 생각합니까? 어쨌든 코드를 다른 방식으로 변경할 때는 다시 컴파일해야하며 단어 목록은 아마도 시간이 지남에 따라 변경 될 가능성 이 가장 적은 코드의 일부일 것입니다 .
JacquesB

3
서브 클래스에서 각 언어의 매우 구체적인 문법 규칙을 코딩 할 수있는 유연성이 구성 파일에서 어떻게 든 동일한 규칙을로드하는 기능보다 결국 더 편리 할 것이라고 생각합니다 (기본적으로 구성을 해석하기위한 자체 프로그래밍 언어).
David K

15

값이 프로그램 논리와 독립적 으로 변경 될 수있는 경우 문자열을 구성 파일 또는 데이터베이스로 추출해야합니다 .

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

  • 리소스 파일로 UI 텍스트 추출 이를 통해 프로그래머가 아닌 사람이 텍스트를 편집하고 교정 할 수 있으며 지역화 된 새 리소스 파일을 추가하여 새 언어를 추가 할 수 있습니다.

  • 연결 문자열, 외부 서비스에 대한 URL 등을 구성 파일로 추출합니다. 이를 통해 서로 다른 환경에서 서로 다른 구성을 사용하고 응용 프로그램 외부의 이유로 변경해야 할 수 있으므로 구성을 즉시 변경할 수 있습니다.

  • 검사 할 단어 사전이있는 맞춤법 검사기. 프로그램 논리를 수정하지 않고 새로운 단어와 언어를 추가 할 수 있습니다.

그러나 구성으로 추출하면 복잡한 오버 헤드가 있으며 항상 의미가있는 것은 아닙니다.

프로그램 논리를 변경하지 않고 실제 문자열을 변경할 수없는 경우 문자열이 하드 코딩 될 수 있습니다 .

예 :

  • 프로그래밍 언어를위한 컴파일러. 각 키워드에는 컴파일러의 코드에서 지원해야하는 특정 의미가 있으므로 키워드는 구성으로 추출되지 않습니다. 새 키워드를 추가하면 항상 코드를 변경해야하므로 구성 파일로 문자열을 추출 할 때 아무런 가치가 없습니다.
  • 프로토콜 구현 : 예 : HTTP 클라이언트는 "GET", "content-type"등과 같은 하드 코딩 된 문자열을 갖게됩니다. 여기서 문자열은 프로토콜 사양의 일부이므로 변경 가능성가장 적은 코드의 일부입니다 .

귀하의 경우에는 단어가 프로그램 논리의 통합 부분이라는 것이 분명하다고 생각합니다 (특정 단어에 대한 특정 규칙을 사용하여 활용기를 작성하기 때문에).이 단어를 외부 파일로 추출하는 것은 가치가 없습니다.

새 언어를 추가하면 각 언어마다 특정 활용 논리가 있으므로 새 코드를 추가해야합니다.


일부 사용자는 임의의 언어에 대한 컨쥬 게이션 규칙을 지정할 수있는 일종의 규칙 엔진 을 추가 할 수 있으므로 새로운 언어를 구성에 의해 순수하게 추가 할 수 있다고 제안했습니다. 인간 언어는 놀랍기 때문에 표현 규칙 엔진이 필요하기 때문에 그 길을 가기 전에 매우 신중하게 생각하십시오. 기본적으로 새로운 프로그래밍 언어 (공액 DSL)를 만들어 모호한 이익을 얻습니다. 그러나 필요한 것은 무엇이든 할 수있는 프로그래밍 언어가 이미 있습니다. 어쨌든 YAGNI.


1
실제로 MainMa에 대한 의견에서 필자는 DSL을 작성하는 것이 의미가 없다고 말하면서 노력할만한 가치가있는 자연 언어는 거의 없기 때문이라고 언급했다. 아마도 프랑스어 / 스페인어 / 이탈리아어는 충분히 가까울 지 모르지만 주어진 언어에서 규칙의 양이 매우 정적 인 것으로 생각하면 추가 노력을 기울일 가치가 없습니다. 복잡성에 대해 언급 한 다른 요점은 내 정확한 걱정이었습니다. 내 질문에서 무엇을 묻 었는지 훌륭하게 이해하고 예제로 큰 대답을했다고 생각합니다. +1!
Chris Cirefice

5

Dan Pichelman의 답변에 100 % 동의하지만 추가 할 것이 하나 있습니다. 여기서 스스로에게 물어야 할 질문은 "누가 단어 목록을 유지 / 확장 / 수정할 것입니까?"입니다. 항상 특정 언어 (특정 개발자, 나는 당신에게)의 규칙을 유지하는 사람이라면, 외부 구성 파일을 사용하는 것이 더 복잡하다면 아무런 이점이 없습니다. 이. 이러한 관점에서, 당신이 경우에도 같은 단어 목록을 하드 코딩 할 수 있도록 감각을 다할 것 때때로을 변경하는 것이 새 버전의 일환으로 새로운 목록을 제공하기에 충분 한,.

반면에 다른 사람이 나중에 목록을 유지할 수있는 기회가 약간 있거나 새 버전의 응용 프로그램을 배포하지 않고 단어 목록을 변경해야하는 경우 별도의 파일을 사용하십시오.


이것은 좋은 지적입니다. 그러나 최소한 앞으로 몇 년간 코드를 실제로 관리하는 유일한 사람이 될 가능성이 큽니다. 이것에 대한 좋은 부분은 문자열이 하드 코딩 될지라도 아주 빨리 변경되지 않는 매우 작은 문자열 / 규칙 세트입니다 (자연 언어이기 때문에 너무 많이 진화하지는 않습니다) -년). 즉, 활용 규칙, 동사 종료 문자열 등은 우리의 일생 동안 동일 할 것입니다. :)
Chris Cirefice

1
@ChrisCirefice ": 정확히 내 요점
Doc Brown

2

하드 코딩 더 나은 동적 로딩 설정 파일보다 잘 여기 것, 그리고 동안에도, 나는 아직도 당신이 엄격 않는 것이 좋습니다 것입니다 분리 하여 데이터 로부터 (동사의 사전을) 알고리즘 . 빌드 프로세스에서 애플리케이션으로 바로 컴파일 할 수 있습니다.

이렇게하면 목록을 유지 관리하는 데 많은 어려움을 겪을 수 있습니다. VCS에서 커밋이 알고리즘을 변경했는지 또는 쉽게 컨쥬 게이션 버그를 수정했는지 여부를 쉽게 식별 할 수 있습니다. 또한 고려하지 않은 경우를 위해 목록을 추가해야 할 수도 있습니다. 특히, 계산 한 32 개의 불규칙 동사의 수가 정확하지 않은 것 같습니다. 그것들이 일반적으로 사용되는 것들을 다루는 것처럼 보이지만, 나는 그들 중 133 또는 350 에 대한 언급을 발견 했습니다.


Bergi, 나는 알고리즘에서 데이터를 분리 할 계획을 세웠다. 프랑스 불규칙에 대한 참고 사항-불규칙에 대한 정의는 전혀 잘못 이해됩니다. 내가 불규칙 하다고 말할 때 의미 하는 것은 '계산'할 수 없거나 동사의 부정사 형태에서만 사용할 수없는 동사입니다. 불규칙 동사는 전혀 특정한 패턴을 갖지 않기 때문에 명시 적으로 열거 된 활용이 필요합니다 (예 : 프랑스어, 동사, 활용, 불규칙). 기술적으로 -ir 동사는 '불규칙'하지만 실제로 고정 된 활용 패턴을 갖습니다.)
Chris Cirefice

0

중요한 부분은 우려의 분리입니다. 이를 달성하는 방법은 관련성이 적습니다. 즉, Java는 괜찮습니다.

규칙이 표현되는 방식에 관계없이 규칙을 변경할 언어를 추가해야합니다. 얼마나 많은 코드와 파일을 편집해야합니까?

이상적으로는 'english.xml'파일을 추가하거나 새로운 'EnglishRules 구현 ILanguageRules'개체를 사용하여 새 언어를 추가 할 수 있어야합니다. 텍스트 파일 (JSON / XML)은 빌드 수명주기 외부에서 텍스트 파일을 변경하려는 경우 이점이 있지만 복잡한 문법, 구문 분석이 필요하며 디버그하기가 더 어려울 수 있습니다. 코드 파일 (자바)을 사용하면 복잡한 규칙을 더 간단하게 표현할 수 있지만 재구성이 필요합니다.

깨끗한 언어 불가지론 적 인터페이스 뒤에 간단한 Java API부터 시작하겠습니다. 두 경우 모두 필요합니다. 원하는 경우 나중에 XML 파일로 지원되는 해당 인터페이스의 구현을 언제든지 추가 할 수 있지만 해당 문제를 즉시 (또는 언제라도) 해결할 필요는 없습니다.

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