강력한 코드 작성 및 오버 엔지니어링


33

과도하게 엔지니어링하지 않고 가능한 가장 강력한 코드를 작성하고 있다는 것을 어떻게 알 수 있습니까?

내 코드가 취할 수있는 모든 가능한 경로에 대해 너무 많이 생각하고 때로는 때로는 시간 낭비처럼 느껴집니다. 나는 그것이 작성중인 프로그램의 종류에 달려 있다고 생각하지만 결코 일어날 수없는 상황을 고려하여 너무 많은 시간을 사용하고 싶지 않습니다.


2
Agda2에서 코딩
SK-logic

구체적인 예는 요점을 밝히는 데 크게 도움이됩니다. :)
João Portela

견고성, 즉 "유효하지 않은 입력 또는 스트레스가 많은 환경 조건에서 시스템이 계속 작동 할 수있는 능력"에 대해 실제로 묻는 지 확인할 수 있습니까?
DJClayworth

나는 기한이 지남에 따라 데모웨어를 사용하기 때문에 완벽하게 마비하지 않고 빨리 해킹 할 수 있습니다.
Job

1
다음은이 주제에 관한 기사입니다. code-tag.com/2017/04/02/…
San

답변:


39

과도하게 엔지니어링하지 않고 가능한 가장 강력한 코드를 작성하고 있다는 것을 어떻게 알 수 있습니까?

강력한 코드는 무엇이라고 생각하십니까? 미래의 증거이며 어떤 상황에서도 대처할 수있는 강력한 코드? 아무도 미래를 예측할 수 없습니다! 복잡하고 유지하기 어려운 엉망이되기 때문에 다시 잘못합니다.

나는 YAGNI (아직)와 KISS 와 같은 다양한 원칙을 따르 므로 불필요한 코드를 작성하지 않습니다. 이는 또한 과도한 엔지니어링을 효과적으로 방지합니다. 확장이 필요할 때 응용 프로그램을 리팩터링합니다. 최신 리팩토링 도구를 사용하면 나중에 필요할 때 인터페이스를 쉽게 만들고 구현을 교환 할 수 있습니다.

그런 다음 가능한 한 강력하게 작성하려고 노력합니다. 여기에는 가능한 많은 경로 (및 상태)와 스파르타 프로그래밍이 필요하지 않습니다 . 큰 도움은 외부 상태에 의존하지 않거나 적어도 실패 할 때 프로그램을 일관성이없는 상태로 두지 않는 "원자"기능 / 방법입니다. 잘하면 스파게티 코드로 끝날 가능성이 거의 없으며 유지 관리에 대한 축복이기도합니다. 또한 객체 지향 설계에서 SOLID 원리는 강력한 코드에 대한 훌륭한 안내서입니다.

실제로 프로그램 경로 또는 상태의 조합 폭발과 같이 복잡성을 줄일 수있는 방법을 깊이있게 생각할 수 있다는 사실을 알게되었습니다. 서브 루틴의 최상의 순서를 선택하고이를 위해이를 설계하여 가능한 조합을 최소한으로 유지하십시오.

강력한 코드는 항상 간단하고 깨끗한 코드이지만 단순성이 항상 쉽게 달성되는 것은 아닙니다. 그러나 당신은 그것을 위해 노력해야합니다. 항상 가능한 가장 간단한 코드를 작성하고 다른 선택이 없을 때만 복잡성을 추가하십시오.

단순성이 강력하고 복잡성이 약합니다.

복잡성이 죽습니다.


2
많은 클래스, 팩토리 및 추상화가 없기 때문입니다. 역설이지만 일부 사람들은 그런 것을 좋아합니다. 왜 그런지 모르겠다.
코더

5
스파르타입니다 !!!
Tom Squires

4
20 년 동안이 일을하지 않은 사람들은 복잡성이 당신을 죽일 수있는 방법을 얻지 못합니다. 그들은 너무 똑똑하다고 생각합니다. 그들은 똑똑하지 않고 바보입니다. 그 복잡성은 당신을 죽일 것입니다.
PeterAllenWebb

1
견고성은 미래를 보장하는 것이 아니라 잘못된 입력 또는 스트레스가 많은 환경에서 계속 작동하는 것입니다-Code Complete p464.
DJClayworth

5
질문자가 내가 이해하는 것과 다른 의미로 '견고한'을 사용하지 않는 한 다른 질문에 대답하고 있습니다. 그는 "나중에 요구할 수 있도록 코드를 작성해야한다"고 묻지 않고 "어떤 특이한 입력 사례를 처리해야하는지"를 묻고있다. YAGNI, KISS 및 SOLID는 관련이 없습니다. 동시에 로그온하려는 백만 명의 사용자를 허용해야합니까? 로그인 이름이 백 슬래시로 시작하면 어떻게됩니까? 이 질문들 중 어느 것도 YAGNI에 의해 답변되지 않았습니다.
DJClayworth

8

균형을 유지하려고 노력합니다.

  • 기존 사용 사례에서 가능한 모든 실행 경로 처리 ( "견고성"부분)
  • 기능 / 요구 사항을 구현할 수있을 것으로 예상됩니다.
  • 코드베이스의 장기간 유지 관리에 필요한 경험을 통해 알고있는 것 (즉, 코드를 깨끗하고 테스트 가능하게 유지).

그것은 퍼지 경계 영역입니다. 때로는 불필요한 작업을 수행하고 때로는 필요한 것으로 밝혀지는 작업을 수행하지 못하는 경우가 있습니다. 그리움이 크지 않으면 괜찮습니다. 여하튼, 나는 나의 실수로부터 배우려고 노력합니다.


기존 사용 사례에서 가능한 모든 실행 경로를 처리하는
CodeYogi

5

강력한 엔지니어링과 오버 엔지니어링의 차이점은 가능한 모든 유스 케이스를 완벽하게 처리하는 것, SHOULDN 'S가 발생하지 않는 기괴한 프린지 유스 케이스의 차이점입니다. 정상적으로 말하면, 사용자는 기괴한 예외 사례를 입력하거나 정의되지 않은 지정되지 않은 기능을 요구하고 정의되지 않은 기능을 요구하고 코드가 충돌하지 않고 정상적으로 종료되거나 지원되지 않는 기능을 사용자에게 알려주는 상황에 처하게됩니다.

반면에 과도한 엔지니어링은 필요하지 않거나 요청하지 않은 기능 (클라이언트가 필요로하지만 요청하지 않은 기능 중 일부)의 완전한 구현 영역에 속하거나 지나치게 복잡한 설계 또는 지나치게 복잡한 설계를 통해 정의 할 수 있습니다. 비교적 간단한 문제를 처리하는 코드.


4

1) 요구 사항을 가져옵니다.

2) 요구 사항을 충족시키기 위해 최소 코드를 작성하십시오. 모호한 것이 있으면 교육받은 추측을하십시오. 매우 모호한 경우 1로 돌아갑니다.

3) 테스트로 보냅니다.

4) 테스터가 좋은 말을하면 승인을 문서화하십시오. 무언가가 꺼져 있으면 1로 돌아가십시오.

테스트 예측이 아닌 테스트 통과에 중점을 둡니다. 테스터가 없다면 ... 테스터를 잡아! 코드 정확성을 검증 할뿐만 아니라 전체 개발 프로세스에 필수적입니다.


1
테스트를 예측하는 것이 아니라 테스트를 통과하는 데 중점을두면 +1이지만, 저와 같은 많은 개발자는 강력한 비즈니스 분석가가 없어도 둘 다 수행 할 것으로 예상됩니다.
maple_shaft

@maple_shaft-매우 사실입니다. 요점은 이러한 문제는 다른 사람의 무능 때문에 발생한다는 것입니다. 다른 사람의 직업에 스트레스를주는 것은 소진의 길입니다. 우리 회사가 한 달 동안 미수금을 할 수있을 정도로 멍청한 경우, 그 결과가 나쁘지 않으면 너무 실망하지 않을 것입니다. 요구 사항을 정의하려면 일반적으로 일상적인 작업을 설명하여 자동화 할 수 있습니다. 직원 중 누구도 그렇게 할 수 없다면 회사가 어려움을 겪을 수 있습니다.
Morgan Herlocker

3

우선 데이터를 최대한 정규화 (중복 아님)하십시오. 데이터가 완전히 정규화 된 경우 데이터를 한 번만 업데이트해도 데이터가 일치하지 않을 수 있습니다.

데이터를 항상 정규화 할 수는 없습니다. 즉, 중복성을 제거하지 못할 수 있으며,이 경우 일관성이없는 상태 일 수 있습니다. 그러면 할 일은 불일치를 용인하고 그것을 정리하고 패치하는 일종의 프로그램으로 주기적으로 복구하는 것입니다.

알림을 통해 중복성을 엄격하게 관리하려는 경향이 강합니다. 이뿐만 아니라가 올바른지하기 어려운, 그러나 발생할 수 있습니다 엄청난 비 효율성. (알림을 작성하려는 유혹의 일부는 OOP에서 실제로 권장되기 때문에 발생합니다.)

일반적으로 이벤트, 메시지 등의 시간 순서에 의존하는 모든 것은 취약 할 것이며 많은 수의 방어 코딩이 필요합니다. 이벤트와 메시지는 한 부분에서 다른 부분으로 변경 사항을 전달하고 불일치를 방지하기 위해 중복성을 갖는 데이터의 특징입니다.

내가 말했듯이, 중복성이 있어야하고 (그리고 기회가 꽤 좋을 경우) a) 허용하고 b) 복구하는 것이 가장 좋습니다. 메시지, 알림, 트리거 등으로 만 불일치를 방지하려고하면이를 강력하게 만드는 것이 매우 어렵다는 것을 알게 될 것입니다.


3
  • 재사용을 위해 작성하십시오.
  • 테스트를 작성하십시오. 사소한, 사소한, 일부 터무니없이 복잡한 것들이 그러한 조건에서 어떻게 처리되는지 봅니다. 테스트는 또한 인터페이스의 형태를 결정하는 데 도움이됩니다.
  • 프로그램이 열심히 실패하도록 작성하십시오 (예 : 어설 션). 내 코드에는 많은 재사용 횟수가 있으며 많은 경우에 대해 테스트합니다. 실제 구현보다 많은 수의 오류 검사 / 처리가 있습니다 (라인 수 기준).
  • 재사용.
  • 잘못 된 것을 즉시 고치십시오.
  • 경험을 통해 배우고 구축하십시오.

오류 발생 하지만 (다행히) 현지화 될 것이며 (대부분의 경우) 테스트 초기에 표시 될 것입니다. 재사용의 또 다른 이점은 클라이언트 / 호출자가 구현에 의해 발생 된 오류 점검 / 스캐 폴딩을 사용하여 대부분의 오류 점검 / 스캐 폴딩을 저장할 수 있다는 것입니다.

시험은 프로그램의 기능과 그 강점을 정의해야한다-성공률과 입력에 만족할 때까지 시험을 계속 추가해야한다. 필요에 따라 개선, 확장 및 강화.


2

나는 잘 정의 된 코드를 작성하여 코드를 작성 함으로써이 구별을하지만, 실행 가능성이 거의없는 최적의 동작은 아닙니다. 예를 들어, 행렬이 양의 양으로 정의 될 것이라고 확신하는 경우 (증명되었지만 테스트되지는 않음) 상태를 테스트하기 위해 프로그램에 어설 션 또는 예외를 삽입하지만 고유 한 코드 경로를 작성하지는 않습니다. 이에 따라 동작이 정의되지만 차선책입니다.


2

견고성 : 유효하지 않은 입력 또는 스트레스가 많은 환경 조건에서 시스템이 계속 작동하는 정도. (코드 완성 2, p464)

여기서 중요한 질문은 견고성이 얼마나 중요한지 묻는 것입니다. Facebook 인 경우 누군가가 입력 할 때 특수 문자를 입력 할 때 웹 사이트가 계속 작동하고 1 억 명의 사용자가 동시에 로그온 할 때 서버가 계속 켜져 있어야합니다. 자신 만 수행하는 일반적인 작업을 수행하기 위해 스크립트를 작성하는 경우 크게 신경 쓰지 않아도됩니다. 그 사이에는 많은 레벨이 있습니다. 필요한 견고성에 대해 판단하는 것은 개발자가 알아야하는 중요한 기술 중 하나입니다.

YAGNI의 원칙은 프로그램에 필요할 수있는 기능을 추가하는 데 적용됩니다. 그러나이 원칙은 견고성에는 적용되지 않습니다. 프로그래머는 주어진 미래 확장이 필요할 가능성을 과대 평가하는 경향이 있지만 (특히 멋진 경우), 잘못 될 가능성을 과소 평가합니다. 또한 이후에 생략 된 기능이 필요한 것으로 밝혀지면 나중에 프로그래머가 작성할 수 있습니다. 결국 생략 된 오류 점검이 필요한 경우 손상이 수행 될 수 있습니다.

따라서 비정상적인 오류 조건을 검사하는 쪽에서 실제로 오류를 범하는 것이 좋습니다. 그러나 균형이 있습니다. 이 균형에서 고려해야 할 사항 :

  • 이 오류는 얼마나 자주 발생할 수 있습니까?
  • 이 오류가 발생하는 비용은 얼마입니까?
  • 내부 또는 외부 용입니까?

사람들이 예상치 못한 방식으로 프로그램을 사용할 수 있다는 것을 잊지 마십시오. 그들이 할 때 예측 가능한 일이 발생하는 것이 좋습니다.

마지막 방어선으로 어설 션 또는 종료를 사용하십시오. 처리 할 수없는 문제가 발생하면 프로그램을 종료하십시오. 일반적으로 프로그램을 계속 진행하여 예측할 수없는 작업을 수행하는 것보다 낫습니다.

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