가장 인기있는 "모범 사례"는 무엇이며 왜 그럴까요? [닫은]


100

"모범 사례"는 우리 산업의 모든 곳에 있습니다. "코딩 모범 사례"에 대한 Google 검색에서 거의 150 만 개의 결과가 나타납니다. 이 아이디어는 많은 사람들에게 위로를 가져다주는 것 같습니다. 지시 사항을 따르면 모든 것이 잘 될 것입니다.

모범 사례 에 대해 읽을 때 ( 예 : 최근 에 Clean Code 에서 몇 개를 읽음) 긴장이됩니다. 이것이 항상 이 방법을 사용해야 한다는 것을 의미합니까 ? 조건이 첨부되어 있습니까? 좋은 습관 이 아닐 수있는 상황이 있습니까? 문제에 대해 더 많이 배울 때까지 어떻게 알 수 있습니까?

Clean Code에 언급 된 몇 가지 관행 은 나와 맞지 않았지만 그것이 잠재적으로 나쁘거나 개인적인 편견인지 아닌지 솔직히 확신하지 못합니다. 기술 업계의 저명한 많은 사람들 이 모범 사례가 없다고 생각하는 것 같습니다 . 따라서 적어도 잔소리가 의심 스럽기 때문에 좋은 회사가되었습니다.

내가 읽은 모범 사례의 수는 여기에 나열하거나 개별 질문을하기에 너무 많기 때문에 일반적인 질문으로 표현하고 싶습니다.

일반적으로 "모범 사례"로 분류 된 코딩 관행은 특정 상황에서 차선책이거나 심지어 해로울 수 있습니까? 그러한 상황은 무엇이며 왜 실천이 열악합니까?

구체적인 예와 경험에 대해 듣고 싶습니다.


8
당신이 동의하지 않는 관행은 무엇입니까? 궁금합니다.
Sergio Acosta

누구나 책을 쓸 수 있고, 그 책에 동의 할 필요는 없습니다. 그렇게 간단합니다.
직업

Steve McConnell의 "Code Complete"라는 책에서 내가 좋아하는 한 가지는 모든 증거를 연구와 증거로 뒷받침한다는 것입니다. Just sayin '
JW01

5
@ 월터 : 이것은 몇 달 동안 열렸는데, 확실히 건설적인 이유는 무엇입니까?
Orbling

2
내 이름이 여기에 언급되는 방식을 살펴보면 여기에 답해야한다고 생각합니다. 여기서 답변은 가치가 있다고 생각하지만 답변은 무효화하지 않으면서도 여론 조사가 덜 확실합니다. 제목 예 : "인기있는 '모범 사례'는 때때로 유해 할 수있는시기와 이유는 무엇입니까?"
Aaronaught

답변:


125

이 말로 머리에 못을 박았다고 생각합니다

나는 액면가로 물건을 가져가는 것을 싫어하고 비판적으로 생각하지 않습니다.

나는 그것이 존재하는 이유에 대한 설명이없는 거의 모든 모범 사례를 무시합니다.

Raymond Chen 은이 기사 에서 다음같이 말합니다.

좋은 조언에는 근거가 포함되어 있으므로 나쁜 조언이 될 때 알 수 있습니다. 왜 무언가를해야하는지 이해하지 못한다면,화물 컬트 프로그래밍의 함정에 빠졌으며, 더 이상 필요하지 않거나 심지어 해로운 상태가 되어도 계속 그렇게 할 것입니다.


4
멋진 인용문.
David Thornley

그 레이몬드 첸 인용문의 다음 단락은 아마도 헝가리어 표기법을 설명하고있을 것입니다! 내가 설명 할 수있는 실질적인 이유없이 그것을 사용하는 대부분의 회사가 있습니다.
Craig

3
그러나 사람들이 모범 사례의 근거가 무엇인지 찾지 않기위한 변명으로 이것을 사용하지 않기를 바랍니다. ;) 불행히도, 나는이 태도를 가진 개발자를 보았습니다.
Vetle

3
근거가 좋다. 연구가 더 좋습니다.
Jon Purdy

7
절대적으로 사실이며, 전에도 같은 말을했습니다. 아마도 "표준"문서의 첫 번째 표준은 "지식을 공유하고 나중에 표준을 철회하는 데 필요한 정보를 제공하기 위해 모든 표준에는 그 이유가 포함되어야합니다"라고 읽어야합니다.
Scott Whitlock

95

이것을 링에 넣을 수도 있습니다.

Premature optimization is the root of all evil.

아뇨.

완전한 인용문 :

"우리는 시간의 97 % 정도의 작은 효율성을 잊어야한다. 조기 최적화는 모든 악의 근원이다. 그러나 우리는 그 중요한 3 %의 기회를 포기해서는 안된다."

, 설계 프로세스 전체 에서 구체적이고 전략적인 성능 향상 을 활용할 수 있습니다 . 이는 성능 목표와 일치하는 데이터 구조 및 알고리즘을 사용함을 의미합니다. 이는 성능에 영향을 미치는 디자인 고려 사항을 알고 있음을 의미합니다. 그러나 또한 그렇게 할 때 엄청나게 최적화하지 않으면 유지 관리 비용을 대가로 약간의 이익을 얻을 수 있습니다.

응용 프로그램을 잘 설계해야하므로 응용 프로그램에 약간의 부하를 가한 후에도 다운되지 않고 응용 프로그램을 다시 작성할 수 있습니다. 축약 된 인용문의 위험은 너무 자주 개발자가이를 수행하기에는 너무 늦을 때까지 성능에 대해 전혀 생각하지 않는 변명으로 사용한다는 것입니다. 사소한 것에 초점을 맞추지 않는다면 처음부터 좋은 성능으로 구축하는 것이 좋습니다.

임베디드 시스템에서 실시간 애플리케이션을 구축한다고 가정 해 봅시다. "초기 최적화는 모든 악의 근원"이기 때문에 프로그래밍 언어로 Python을 선택합니다. 이제 파이썬에 반대하는 것은 없지만 해석 된 언어입니다. 처리 능력이 제한되어 있고 실시간 또는 거의 실시간으로 일정량의 작업을 수행해야하고 작업에 더 많은 처리 능력이 필요한 언어를 선택하는 경우, 당신은 엄청나게 무너집니다. 이제 유능한 언어로 시작해야합니다.


4
강한 +1 , 그렇지 않습니다.
Stephen

21
그러나 하나의 특정 최적화가 그 중요한 3 % 내에 있다는 것을 이미 알고 있다면 최적화를 조기에 수행하고 있습니까?
John

7
@Robert : 그렇다면 "조기 최적화는 모든 악의 근원"이라는 진술에 동의하지 않는 점은 무엇입니까?
John

8
언어 선택과 같은 고급 디자인과 기술적 결정을 최적화하는 것은 결코 시기상조가 아닙니다. 그러나 종종 비 효율성이 생기는 디자인을 대부분 완성한 후에야 대부분의 팀이 의도 여부에 관계없이 대부분의 팀이 버림 버전을 작성한다고 Fred Brooks는 말했습니다. 프로토 타이핑에 대한 또 다른 논쟁.
Dominique McDonnell

8
@Robert, Knuth 견적은 조기에 최적화되었습니다.

94

기능 / 방법 당 하나의 리턴.


7
나는 이것을 넣을 예정였다. 나는 초기 반품 진술을 좋아한다.
카슨 마이어스

4
물론! 사람들은 초기 return진술 을 피하기 위해 꽤 흥미로운 프로그램 흐름을 고안 합니다. 깊이 중첩 된 제어 구조 또는 지속적인 점검. 이것은 실제로이 if return문제를 단순화 할 수있을 때 방법을 부 풀릴 수 있습니다 .
snmcdonald

4
가드를 제외하고 함수에서 여러 개의 리턴이 필요한 경우 함수가 너무 길 수 있습니다.
EricSchaefer

18
여러 위치에 표시되지 않는 한 리턴 키워드를 갖는 것은 중요하지 않습니다. 일찍 돌아오고 자주 돌아옵니다. 코드를 더 단순화하는 데만 도움이됩니다. 사람들이 속보 / 연속 진술이 어떻게 작동하는지 이해할 수 있다면 왜 돌아 오는 데 어려움을 겪습니까?
Evan Plaice

7
나는 이것이 매우 오래된 모범 사례라고 생각합니다. 나는 그것이 현대적인 모범 사례라고 생각하지 않습니다.
Skilldrick

87

바퀴를 재발 명하지 마십시오 . 널리 사용되는 교리입니다. 적절한 솔루션이 존재하면 자신 만의 솔루션을 만드는 대신 솔루션을 사용하는 것이 좋습니다. 노력을 절약하는 것 외에도 기존 솔루션은 처음에 생각했던 것보다 더 잘 구현 (버그 프리, 효율적, 테스트) 될 것입니다. 여태까지는 그런대로 잘됐다.

문제는 100 % 적합한 솔루션이 거의 없다는 것입니다. 80 % 적합한 솔루션이 존재할 수 있으며 사용하는 것이 좋습니다. 그러나 60 % 정도는 어떻습니까? 40 %? 선은 어디에서 그리나요? 선을 그리지 않으면 "바퀴 재발견"을 피하기 위해 10 %의 기능을 사용하기 때문에 부풀린 라이브러리를 프로젝트에 통합 할 수 있습니다.

바퀴를 재발견하면 원하는 것을 정확하게 얻을 수 있습니다. 또한 바퀴 만드는 법도 배웁니다. 수행함으로써 학습을 과소 평가해서는 안됩니다. 그리고 결국, 커스텀 휠은 상용 휠보다 낫습니다.


3
나는 다른 방법으로 이런 일이 일어났다. 필자는 원하는 것을 수행하지 않았지만 나중에 Ext JS 그리드로 교체했기 때문에 자체 아약스 그리드 구성 요소를 만들었습니다. 처음부터 디스플레이 레이어가 교체 될 것이라고 가정했습니다.
Joeri Sebrechts

20
동의했다. 아무도 바퀴를 재발 명하지 않으면 우리는 모두 나무 타이어로 자동차를 운전할 것입니다.
윌리 박사의 견습생

6
C ++ 프로젝트에 Boost를 추가하면 항상 10 %의 예처럼 느껴집니다. 난 항상 직접 그것의 10 % 미만이 필요하지만, 물론 다른 모듈을 가져 오는 다른 모듈을 가져와야하는 기능들 ...
Roman Starkov

3
+1 : 이번 주에, 나는 바퀴를 재발 명했다 (예를 들어 우리가 아직 모듈화 한 요구에 맞는 부풀면서도 인기있는 jquery 플러그인을 대체 함). 또한 말 그대로 바퀴를 재발 명하는 사람들이 있습니다. 예를 들어 미쉐린을 예로 들어 타이어를 개선하기 위해 R & D를 수행합니다.
wildpeaks

2
@Dr. 교묘하게, 그 바퀴는 재발견되지 않았고, 리팩토링되었습니다!

78

"모든 단위 테스트."

나는 모든 코드가 단위 테스트를해야한다고 들었습니다. 메소드에 대한 테스트가있는 경우 해당 메소드의 출력 또는 구조에 대한 변경은 두 번 (코드에서 한 번, 테스트에서 한 번) 수행해야합니다.

따라서 단위 테스트는 코드의 구조적 안정성에 비례해야한다고 생각합니다. 아래에서 위로 계층 시스템을 작성하는 경우 데이터 액세스 계층에서 wazoo를 테스트합니다. 내 비즈니스 로직 계층은 꽤 잘 테스트되고 프레젠테이션 계층에는 몇 가지 테스트가 있으며 뷰에는 테스트가 거의 또는 전혀 없습니다.


7
"Unit Test Everything"이 "조기 최적화"인용과 같은 진부한 것으로 생각됩니다. 나는 일반적으로 귀하의 비율에 동의하며, 응용 프로그램 계층 객체를 조롱하기 위해 엄청난 노력을 기울이는 개발자의 많은 사례를 보았습니다.
Robert Harvey

36
분석법의 구조가 변경되면 테스트가 변경되는 경우 테스트가 잘못되었을 수 있습니다. 단위 테스트는 구현을 검증하지 말고 결과 만 확인해야합니다.
Adam Lear

7
@Anna Lear : 설계 / 구조 변경 (리팩토링)에 대해 이야기 한 것 같습니다. 디자인이 충분히 성숙하지 않기 때문에 더 좋은 방법을 찾으면 많은 테스트를 수정해야 할 수도 있습니다. 나는 당신이 더 숙련 된 테스터 일 때 (이 이유와 다른 이유로 인해) 테스트가 나쁜 아이디어가 될 곳을 더 쉽게 알 수 있지만 디자인이 실제로 성숙하지 않다면 여전히 방법.
n1ckp

13
이것이 "먼저 테스트"아이디어가 효과가없는 이유라고 생각합니다. 먼저 테스트를 수행하려면 디자인 권한이 있어야합니다. 그러나 디자인이 제대로 되려면 작업을 시도하고 작동 방식을 확인하여 개선 할 수 있어야합니다. 따라서 디자인을하기 전에 실제로 테스트를 수행 할 수 없으며 디자인을 올바르게하려면 코드를 작성하고 작동 방식을 확인해야합니다. 정말 우버 아키텍처가 없으면 아이디어가 어떻게 작동하는지 알 수 없습니다.
n1ckp

13
@ n1ck TDD는 실제로 디자인 연습만큼이나 테스트 연습이 아닙니다. 아이디어는 테스트를 통해 기존 디자인에 적합하지 않고 테스트를 통해 디자인을 발전시키는 것입니다 (나쁘거나 불충분 한) 테스트에 적합합니다. 따라서 테스트를 먼저 수행 할 디자인 권한이 없어도됩니다.
Adam Lear

57

항상 인터페이스에 프로그래밍하십시오.

때로는 하나의 구현 만있을 수 있습니다. 인터페이스 추출 과정을 필요로 할 때까지 인터페이스 추출 프로세스를 지연 시키면 필요하지 않은 경우가 종종 있습니다.


4
합의하면 인터페이스가 필요할 때 인터페이스에 프로그래밍합니다 (예 : 안정적인 API를 사용하여 작업).
Robert Harvey

45
내 독서 에서이 규칙은 언어 구조로서의 인터페이스에 관한 것이 아닙니다. 즉, 메서드를 호출 할 때 클래스의 내부 작업에 대해 어떤 가정도하지 말아야하며 API 계약에만 의존해야합니다.
Zsolt Török

2
흥미로운 질문이 있습니다. 주로 .NET 개발자이므로 제 인터페이스는 IBusinessManager 또는 IServiceContract처럼 보입니다. 나에게 이것은 탐색하기가 매우 쉽습니다 (그리고 일반적으로 인터페이스를 다른 네임 스페이스 (또는 다른 프로젝트)에 유지합니다). Java를 사용했을 때 실제로이 혼란스러운 것을 발견했습니다 (일반적으로 내가 본 인터페이스 구현에는 .impl이 붙어 있으며 인터페이스에는 묘사가 없습니다). 이것이 코드 표준 문제 일 수 있습니까? 물론 자바의 인터페이스는 코드를 복잡하게 만듭니다. 언뜻보기에 일반 클래스와 똑같이 보입니다.
Watson

5
@Watson : 하나의 비용은 Eclipse의 메소드 호출에서 F3 ( '선언으로 점프')을 누를 때마다 하나의 구현이 아닌 인터페이스로 이동하는 것입니다. 그런 다음 Control-T, 아래쪽 화살표를 눌러 구현에 도달해야합니다. 또한 일부 자동 리팩토링을 차단합니다. 예를 들어 인터페이스 정의에서 메소드를 인라인 할 수 없습니다.
Tom Anderson

4
@Tom : 글쎄요, 이클립스 vs. Intellij-나는 그 전쟁에 기꺼이 참여 하겠지만, 나는 명백한 장애가있는 사람과 신체적 대결을 겪지 못하게하는 뛰어난 도덕법을 가지고 있습니다. 팔. 나는 이클립스가 나쁘다고 말하는 것이 아니다. 만약 엑시스 파워가 그것을 사용하여 그들의 전쟁 기계를 제작하거나 디자인했다면, WWII는 이제 "2 일 커 커플"로 알려져있을 것이다. 진지하게, 나는 기성품 IDE (Intellij / VS + ReSharper)에서 얻을 수있는 광택이 부족하다는 것을 알았습니다. 나는 한 번 이상 그것을 싸우는 것을 발견했다.
Watson

46

오픈 소스를 사용하지 마십시오 (또는 .NET 개발자를위한 비 Microsoft)

Microsoft가 개발하지 않은 경우 여기에서 사용하지 않습니다. ORM-EF를 사용하고 싶습니다, IOC-Unity를 사용하고 싶습니다-기록하려는 엔터프라이즈 로깅 응용 프로그램 블록. 더 나은 라이브러리가 많이 있지만 여전히 개발 세계의 달러 메뉴에서 주문을 계속하고 있습니다. "McDonald 's Nutritional Guidelines"라고 생각하는 Microsoft Best Practices를들을 때마다 맹세합니다. 물론, 당신이 그들을 따르면 아마 살 것이지만 영양 실조와 과체중이 될 것입니다.

  • 참고이되지 않을 수도 있습니다 당신의 가장 좋은 방법,하지만 일반적인 하나의 거의 모든 곳에서 내가 작업 한 다음입니다.

13
끔찍한 소리 ... = (하지만 아마 다른쪽에 너무 많이 있지만 가능한 한 M $을 피합니다.
Lizzan

그렇게해서는 안됩니다. 라이브러리는 누가 만들 었는지 고려하지 않고 그 가치에 따라 선택해야합니다. 예를 들어, 나는 EF를 좋아하지만 Enterprise Library에 대한 나쁜 경험이 있었고 FluentValidation, log4net 및 Elmah와 같은 검증 및 로깅을위한 더 나은 도구를 발견했습니다.
Matteo Mosca

4
IBM ^ wMicrosoft
Christopher Mahan

17
미러 이미지 버전도 있습니다. 즉, Microsoft를 사용하지 않거나 비용을 지불하지 않아야합니다.
Richard Gadsden

5
나는 이것이 널리 인정받는 교리가 아닌 조직에서 일하기에 충분히 운이 좋지만, 우리가 상업적 솔루션을 채택한 곳에서는 확실히 많은 고통이 있습니다. 상용 솔루션의 일부가 제대로 작동하지 않을 때 문제가 발생합니다. 공개 소스 인 경우 소스 (최종 문서)를보고 무엇이 잘못되었는지 확인할 수 있습니다. 비공개 소스를 사용하면 자신이 사용 하는 제품에 대해 잘 모르는 기술 지원 지식에 액세스 할 수있는 권한 을 지불 해야합니다. 그리고 이것이 유일하게 사용 가능한 '수정'입니다.
SingleNegationElimination

40

객체 방향

코드가 "객체 지향"이기 때문에 마술처럼 좋다는 가정이 있습니다. 그래서 사람들은 객체 지향적 인 기능을 클래스와 메소드로 짜 넣습니다.


7
Object Orientation이 제공하는 조직을 이용하지 않고 상당한 규모의 소프트웨어 시스템을 구축하는 것을 상상할 수 없습니다.
Robert Harvey

18
로버트. 유닉스는 객체 지향적이지 않으며 상당한 크기의 소프트웨어 시스템으로 자격이 있습니다. 그것은 또한 꽤 인기있는 것 같습니다 (Mac OSX, iPhone, Android 전화 등을 생각하십시오)
Christopher Mahan

7
내가 의미하는 바는 우리가 가장 적절한 방법론을 사용해야한다고 생각합니다. 나는 사람들이 "객체 지향적"이기 때문에 성 가시고 이해가되지 않는 방법과 클래스를 사용하는 것을 보았습니다. 화물 컬트입니다.
LennyProgrammers

8
은 총알이 없습니다. 함수형 프로그래밍 (Haskell)은 객체 지향적이지 않고 상당히 성공적입니다. 하루가 끝나면 여러 도구를 사용할 수 있으며 작업에 가장 적합한 구색을 선택하는 것이 귀하의 임무입니다.
Matthieu M.

9
재미있는 점은 클래스, 다형성 등을 사용하는 것 외에도 대부분 객체 지향 코드가 실제로 절차 적 코드라는 것입니다.
Oliver Weiler

35

모든 코드에 주석을 달아야합니다.

아닙니다. 언젠가 당신이 명백한 코드를 가지고 있다면, 예를 들어 setter는 특별한 것을 할 때까지 주석을 달지 않아야합니다. 또한 왜 이것을 언급해야합니까?

/** hey you, if didn't get, it's logger. */
private static Logger logger = LoggerFactory.getLogger(MyClass.class);

13
모든 코드는 이해할 수 있어야합니다 . 주석은 그에 대한 주요 도구이지만 유일한 도구는 아닙니다.
Trevel

당연히 코드는 이해할 수 있어야합니다. 그러나 메소드 이름과 같이 아무것도 추가하지 않는 주석을 작성해야 할 이유는 없습니다. 당신이 글을 쓴다면 /** sets rank. */ void setRank(int rank) { this.rank = rank; }나는 그 의견을 멍청한 것으로 가정합니다. 왜 쓰여졌습니까?
블라디미르 이바노프

2
생성 된 문서. 그것이 형식 주석 /** */대신 형식입니다 /* */. 또는 .NET의 경우///
Berin Loritsch

10
사용 }//end if, }//end for, }//end while내가 만난 주석 낭비의 가장 좋은 예이다. 나는 오프닝 브레이스가 위의 2 줄을 넘지 않는 것을 여러 번 보았습니다. 당신은 이럴 경우 필요 이 후 주석 코드의 요구 ... 다시 인수 분해를하거나 $ 20 조랑말 중괄호 일치 하이라이트는 IDE / 텍스트 편집기를 구입해야합니다.
scunliffe

7
코드는 "어떻게"라고 말합니다. 의견은 "왜"라고 말해야합니다.

32

방법론, 특히 스크럼. 어른들이 "Scrum Master"라는 문구를 사용한다고 들었을 때 똑바로 얼굴을 유지할 수 없습니다. 나는 개발자 시위에 너무 지쳐서 Methodology X의 일부 측면이 회사를 위해 일하지 않고 Guru So-and-So에게만 들려야합니다. "방법론 X. Padawan 학습자, 스크럼이 더 어려워 야합니다!"

민첩한 방법론 (많은 것들)에는 많은 지혜가 있지만, 종종 많은 분뇨에 갇혀 개그 반사에 맞설 수 없습니다. Wikipedia의 스크럼 페이지 에서이 비트를 가져옵니다 .

Scrum에는 많은 역할이 정의되어 있습니다. 모든 역할은 개발 과정에 관여하는 특성에 따라 돼지와 닭의 두 가지 그룹으로 나뉩니다.

정말? 돼지와 닭 이라고요? 매혹적인! 이것을 내 상사에게 던지기를 기다릴 수 없다 ...


흥미 롭군 어느 정도 동의합니다. 그러나 마지막 부분으로, 원하는 것을 호출하십시오. 니모닉입니다. 그게 전부입니다.
Steven Evers

12
+1 ... 맞습니다. 진지하게 받아들이 기 어렵습니다. <큰 호황> * 스크럼
마스터입니다

2
그리고 비유. 그것은 교회 설교 나 자조 전문가 (및 코미디언)가 유명한 일종의 일화를 떠올리게합니다. "친구 스티브를 데려가십시오. 스티브는 아내 셰릴과 끊임없이 논쟁하고있었습니다. 결혼 생활이 실제로 위험에 처한 시점. 언젠가 ... "이런 종류의 실은 다른 분야에서 저를 귀찮게하지는 않지만, 공학 분야에서 그들이 번식하는 것을 싫어합니다.
evadeflow

2
스크럼 닌자 어때요?
Berin Loritsch

1
나는 "돼지와 닭"비교에 동의하지 않습니다 ... 그것은 애자일 선언문 앞에서 직접 비행합니다. 즉, "계약 협상을 통한 고객 협업"입니다. 고객은 프로젝트 팀으로서 프로젝트의 성공에 투자합니다. 일부 역할의 돼지와 다른 역할의 닭을 호출하면 IMHO가 성공적인 프로젝트의 가장 큰 장애물이된다는 "우리와 그들"의 사고 방식이 설정됩니다.
Michael Brown

25

객체 관계형 매핑 ... http://en.wikipedia.org/wiki/Object-relational_mapping

데이터에서 추상화되기를 원치 않으며 정확한 제어 및 최적화를 잃고 싶지도 않습니다. 이 시스템들에 대한 나의 경험은 극도로 열악했다 ...이 추상화 계층들에 의해 생성 된 질의들은 내가 오프쇼어링에서 본 것보다 훨씬 나쁘다.


19
조기 최적화는 모든 악의 근원입니다. 느린 코드는 실제로는 유지 관리 할 수없는 코드와 비교할 때 거의 문제가되지 않습니다. ORM을 사용하고 필요할 때만 추상화를 잘라내십시오.
Fishtoaster

28
ORM은 80-20 도구입니다. 그것들은 80 % CRUD를 처리하기 위해 만들어졌으며, 그 후에 끝없는 배관 코드를 모두 작성하기에는 너무 번거로워졌습니다. 다른 20 %는 저장 프로 시저 사용 및 일반 SQL 쿼리 작성과 같은보다 "기존"방식으로 수행 할 수 있습니다.
Robert Harvey

18
@Fishtoaster : "우리는 시간의 97 % 정도의 작은 효율성을 잊어야합니다. 조기 최적화는 모든 악의 근원입니다. 그러나 우리는 그 중요한 3 %의 기회를 포기해서는 안됩니다."?
Robert Harvey

5
@Robert Harcey : 직접 인용문을 사용하지 않은 이유가 있습니다. 대부분의 프로그래머는 효율성에 너무 집중한다고 생각합니다. 실제로 해결해야 할 문제는 거의 없습니다. 물론 다른 도메인보다 중요한 특정 도메인이 있지만 유지 관리 성과 확장 성은 어디에서나 문제가됩니다. 또 다른 수정 된 인용문 : "작동하게하고, 유지 보수 가능하게하고, 읽을 수있게 만들고, 확장 가능하게하고, 테스트 가능하게 한 다음 , 시간이 있고 필요할 경우 신속하게 처리하십시오."
Fishtoaster

12
@Craig : 당신의 진술에서 아이러니를 어떻게 인식하지 못했습니까? 연간 필요로하는 것은 ORM에서 좋은 성능을 확보하는 방법에 대해 자세히 알아 것은입니다 우수한 인수 에 대한 "통제"는 SQL 생산 및 저장 프로 시저를 주입 할 필요가있는 한,으로 ORMs. 이에 대한 지식이 있으면 ORM을 완전히 우회 할 지식이 있습니다.
니콜라스 나이트

22

영어 문장처럼 함수 이름 작성

Draw_Foo()
Write_Foo()
Create_Foo()

등등. 이것은 멋지게 보일지 모르지만 API를 배울 때 고통 스럽습니다. "Foo로 시작하는 모든 것"에 대한 색인을 검색하는 것이 얼마나 쉬운가요?

Foo_Draw()
Foo_Write()
Foo_Create()

기타


2
TM의 기능 목록에 Foo를 입력하는 것만 큼 쉽습니다.
Josh K

68
당신이 원하는 실제로 것 같은데 Foo.Draw(), Foo.Write()그리고 Foo.Create()당신이 할 수 있도록, Foo.methods.sort또는Foo.methods.grep([what I seek]).sort
Inaimathi

7
'Get'으로 시작하는 것이 또 다른 예입니다.
JeffO

1
나는 objective-c 세계에서 왔으며 java (내 다른 삶)를 할 때 자세한 메소드 이름과 접두사 표기법을 크게 그리워합니다. 코드 완성이 작동하기 시작한 이후로 여분의 타이핑 문제도 발견하지 못했습니다.

2
@Scott 틀록 : 아니 어떤 .NET 개발자를위한 최신이, IIRC, VS 2008 그렇게하지 않았다. 그러나 2010 년은 환상적입니다.
Steven Evers

22

MVC-MVC 접근 방식에서 많은 웹 디자인 문제를 해결하는 것이 단순성 또는 구조보다는 프레임 워크 (레일 등)를 행복하게 만드는 것보다 더 자주 발견됩니다. MVC는 단순성에 비해 과도한 비계를 중요하게 생각하는 "아키텍처 우주 비행사"가 선호합니다. ymmv.

클래스 기반 OO-제 생각에는 변경 가능한 상태의 복잡한 구조를 권장합니다. 몇 년 동안 클래스 기반 OO에서 찾은 유일한 강력한 사례는 OO 책의 1 장을 구성하는 각질 "모양-> 사각형-> 사각형"예입니다.


4
ASP.NET 및 ASP.NET MVC에서 웹 개발을 수행했으며 MVC가 비계처럼 보이지만 단순성, 유지 관리 성 및 마크 업에 대한 뛰어난 제어 등 여러 가지 이유로 ASP.NET보다 선호합니다. 모든 것이 그 자리를 차지하고 있으며, 모든 것이 조금 반복되는 것처럼 보이지만 유지하는 것은 기쁨입니다. 그것은 완전히 사용자 정의 할 수 있으므로, 즉시 행동을 좋아하지 않으면 변경할 수 있습니다.
Robert Harvey

1
OO에 관한 한, 좋은 방법과 나쁜 방법이 있습니다. 상속은 과대 평가되었으며 실제 책에서는 대부분의 책에서 생각하는 것보다 더 적게 사용됩니다. OO 세계에서도 더 기능적이고 불변의 개발 스타일로 향하는 추세가 있습니다.
Robert Harvey

1
MVC를 언급하면 ​​+1입니다. MVC (데이터 계층 논리, 프리젠 테이션 논리 및 백그라운드 논리 분리)는 물리적으로 코드 스 니펫을 포함하는 파일의 혼동으로 복잡한 폴더 계층 구조로 분리하는 개념은 좋지 않습니다. 필자는 PHP의 네임 스페이스 지원 부족과 수십 년 전의 기술을 '최신의 것'으로 영화 롭게하는 초보자 개발자에게이 모든 현상을 비난합니다. 간단하고 데이터베이스 접근 자, GUI 및 배경 논리 (필요한 경우 하위 네임 스페이스)를위한 네임 스페이스를 만듭니다.
Evan Plaice

3
OO의 경우 프로젝트 관리가 복잡성 관리가 중요한 크기로 커질 때까지 이점이 실제로 보이지 않습니다. 가능한 한 단일 책임 원칙을 따르고 코드에 공개적으로 노출 된 경우 (예 : .dll의 경우) 코드를보다 안전하게 만들고 API를 단순화하기 위해 클래스 / 메소드 / 속성의 내부 구현을 숨기십시오.
Evan Plaice

1
나는 개인적으로 가장 우아한 인수 중 하나가 될하기까지 형태> rectangle-> 평방 예를 찾을 수 에 대한 OOP. 예를 들어 Square(10).Draw()충분합니다 Rectangle(10, 10).Draw(). 사각형이 사각형의 하위 클래스라는 것을 의미합니다. 그러나 mySquare.setWidthHeight(5,10)넌센스 (IE, Liskov 대체 원칙에 실패), 사각형은 높이와 너비가 다를 수 없지만 사각형은 사각형의 하위 클래스임을 의미합니다. 이것은 다른 문맥에서 "원, 타원 문제"로 알려져 있습니다
SingleNegationElimination

22

야 그니

( 넌 필요 없어 )

이 접근 방식은 기존 코드베이스에서 기능을 구현해야했던 시간과 시간이 많이 들었습니다.이 계획을 신중하게 계획하면 이러한 기능이 미리 포함되었을 것입니다.

내 아이디어는 종종 YAGNI 때문에 거부 당했으며, 대부분 누군가가 그 결정에 대해 나중에 지불해야했습니다.

(물론 잘 설계된 코드베이스는 나중에 기능을 추가 할 수는 있지만 현실은 다르다고 주장 할 수 있습니다)


15
YAGNI에 동의하지만 무엇을 받고 있는지 확인합니다. YAGNI의 요점은 모든 것을 아주 세부적 으로 계획하려는 사람들을 다루는 것입니다 . 그러나 열 번 중 아홉 번은 엔지니어 코드를 작성하거나 계획을 완전히 건너 뛰는 변명으로 사용됩니다.
Jason Baker

12
P.Floyd, @Jason Baker : +1 물론입니다. 오래된 말은 "실험실에서 몇 달 동안 도서관에서 시간을 절약 할 수 있습니다"
Steven Evers

사양은 종종 대부분의 구현을 남겨두고 일부 인터페이스는 열린 상태로 둡니다. 구현 결정, 사용자가 볼 수있는 인터페이스 또는 기타 어떤 것이 든 사양에 직접적으로 포함되지 않고 사양을 구현하기 위해 필요한 모든 것 또한 사양의 간접적 인 요구 사항입니다. 기능이 사양에없고 사양에 의해 암시되지 않은 경우에는 필요하지 않습니다. 이것이 어떻게 혼동 될 수 있습니까?
SingleNegationElimination

1
@TokenMacGuy 중요한 부분은 사양 부분에 내포되어 있습니다. 그것은 의견이 많이 다른 곳입니다.
Sean Patrick Floyd

20

SQL의 경우

  1. 트리거를 사용하지 마십시오
  2. 뷰 뒤에 항상 테이블 숨기기

순서대로 :

  1. 그것들은 그 자리에있는 기능입니다. 테이블에 대한 여러 업데이트 경로가 있거나 100 % 감사가 필요합니까?

  2. 왜? 계약을 유지 관리하기 위해 리팩토링을하고 싶지만 테이블 변경 사항과 일치하도록보기를 변경했을 때가 아닙니다.

편집하다:

3 번 : 존재하지 않는 * 1/0을 시도하십시오. 효과가있다. 열 목록은 SQL 표준에 따라 평가되지 않습니다. 191 화


3
# 2가 모범 사례입니까?
Hogan


1
@Hogan : 기본 테이블을 단순히 미러링하는 뷰는 기본 테이블을 직접 사용하는 것보다 보안을 추가하지 않습니다. securityuser 테이블에 조인하거나 일부 열을 마스크하면 충분합니다. 그러나 테이블이나 뷰에서 모든 열을 선택하십시오. 차이가 없습니다. 개인적으로, 나는 저장된 procs를 어쨌든 사용합니다.
gbn

3
@Hogan : 나는 :-) SQL 서버에 대해 뭔가 알고 stackoverflow.com/users/27535/gbn 내 말하는 GRANT SELECT 테이블에 뷰가 SELECT 인 경우 SELECT ON보기을 부여하는 다르지 않다입니다 * 테이블에서
GBN

1
@gbn : 동의합니다. 차이가 없습니다. 우리도 같은 말을하고 있다고 생각합니다. 내 원래 의견 ( "# 2는 모범 사례입니까?")이 개인적 경험에 기반한 것으로 생각되는데 (트리거와 같은)보기가 올바르게 사용되는 것보다 자주 사용되지 않습니다. 따라서 그러한 모범 사례는 남용을 향상시키지 않을뿐입니다. 모범 사례로 여겨지면 100 % 맞습니다.
Hogan

20

주로 디자인 패턴. 사용률이 너무 높거나 적습니다.


13
+1 여전히 디자인 패턴이 어떻게 아름답고 우아한 솔루션인지는 모르겠습니다. 언어 부족에 대한 해결책입니다.
Oliver Weiler

2
언어 자체를 사용하여 언어 냄새를 근절하려는 노력으로 보아라.
Filip Dupanović가

15

단일 책임 원칙

( "모든 수업은 하나의 책임만을 가져야합니다. 즉, 모든 수업은 변경해야 할 이유가 하나뿐이어야합니다")

동의하지 않습니다. 메소드 는 변경해야 할 이유가 하나만 있어야 한다고 생각하고 클래스의 모든 메소드는 하나와 논리적 관계를 가져야 하지만 클래스 자체는 실제로 여러 가지 (관련) 작업을 수행 할 수 있습니다 .

내 경험에 따르면,이 원칙은 너무 열심 적으로 적용되기 때문에 많은 작은 1 가지 방법 클래스가 생깁니다. 내가 일한 민첩한 상점들이이 일을 해냈습니다.

.Net API의 작성자 가 List.Sort (), List.Reverse (), List.Find () 등이 아니라 이러한 사고 방식 을 가지고 있다고 가정하면 ListSorter, ListReverser 및 ListSearcher 클래스가 있습니다!

더 이상 SRP (이론 자체로는 끔찍한 것은 아님) 에 대해 논쟁하는 대신 , 나는 오래 지속 된 일화 경험을 공유 할 것입니다.


내가 일을 한 곳에서, 나는 아주 간단한 썼다 최대 흐름 해결사 노드, 그래프하는를 해결하기 위해 그래프 제작자 / 솔버를 사용하는 그래프 제작자, 그래프 해결사, 그리고 클래스 : 다섯 개 가지 클래스로 구성 실제 문제. 특별히 복잡하거나 긴 것은 없었습니다 (솔버는 ~ 150 라인에서 가장 길었습니다). 그러나 클래스에 "책임"이 너무 많은 것으로 결정되어 동료가 코드 리팩토링을 설정했습니다. 그들이 끝났을 때, 나의 5 개의 수업은 25 개의 수업으로 확장되었고, 그의 총 코드 라인은 원래의 3 배 이상이었습니다. 코드의 흐름은 더 이상 명확하지 않았으며 새로운 단위 테스트의 목적도 아니 었습니다. 나는 이제 내 코드가 무엇을하는지 알아내는 데 어려움을 겪었다.


같은 장소에서, 거의 모든 클래스는 하나의 메소드만을 가졌습니다 ( "책임 성"만). 프로그램 내에서의 흐름을 따르는 것은 거의 불가능했으며, 대부분의 단위 테스트는 이 클래스다른 클래스의 코드라고 불리는 테스트로 구성되었으며 두 가지 목적 모두 나에게 미스터리였습니다. 말 그대로 수백 개의 클래스가 있었으며 (IMO) 수십 개가 있어야했습니다. 각 클래스는 하나의 "thing" 을 수행했지만 "AdminUserCreationAttemptorFactory" 와 같은 이름 지정 규칙을 사용하더라도 클래스 간의 관계를 파악하기가 어려웠습니다.


다른 곳 ( 클래스- 만해야하는 방법론-일정한 사고 방식을 가짐 )에서 특정 작업 중에 95 %의 시간이 걸리는 방법을 최적화하려고했습니다. (어리석게) 조금 최적화 한 후, 그것이 bajillion 시대라고 불리는 지에 관심을 돌 렸습니다 . 클래스의 루프에서 호출되었습니다 ... 다른 클래스의 루프에서 메소드가 호출되었습니다. 또한 루프에서 호출되었습니다 ..

모두 13 단계에 걸쳐 5 단계의 루프가 존재한다고한다. 어떤 클래스가 실제로하고 있는지는 그것을보고 판단하기가 불가능했습니다. 어떤 메소드를 호출했는지, 어떤 메소드를 호출했는지 등의 정신 그래프를 스케치해야했습니다. 그것이 하나의 방법으로 묶여 있다면, 우리의 문제 방법이 즉시 명백한 5 개의 루프 레벨 안에 중첩되어 약 70 줄에 불과했을 것입니다.

13 개의 클래스를 하나의 클래스로 리팩토링하라는 요청이 거부되었습니다.


6
누군가가 "Pattern Fever"또는이 경우 "Principle Fever"를받은 것처럼 들립니다. 목록 클래스는 SRP를 위반하지 않습니다. 모든 기능은 하나의 목적으로 사용되며 객체 모음을 조작합니다. 수업에서 하나의 기능 만 갖는 것은 나에게 과잉 소리처럼 들립니다. SRP의 기본 원리는 코드 단위 (방법, 클래스 또는 라이브러리)가 간결하게 언급 할 수있는 단일 책임을 가져야한다는 것입니다.
Michael Brown

3
순수한 기능 코드를 작성하는 것이 불가능한 사람들로부터 이런 종류의 광기를보기 시작했습니다. 세상의 모든 문제를 패턴 책으로 해결할 수 있다는 것을 너무 많이 교육합니다. 실용주의에 대해 충분히 생각하지 못했습니다. 당신처럼 나는 클래스 기반 OO 코드가 너무 끔찍한 것을 보았습니다. 따라서 그것을 따르는 것은 완전히 불가능합니다. 그리고 거대하고 부풀어 오른다.
quick_now

3
여기에 두 번째 코멘트. "원칙"이 많이 적용되었습니다. 때로는 정반대의 행동이 적절한 경우 좋은 아이디어가 많이 있습니다. 좋은 프로그래머는 규칙을 어기면 알게됩니다. 규칙은 "규칙"이 아니기 때문에 "정말 멍청한 생각을 제외하고는 대부분의 경우 모범 사례"에 대한 진술입니다.
quick_now

".Net API 작성자가 List.Sort (), List.Reverse (), List.Find () 등이 아니라 이러한 사고 방식을 가지고 있다고 가정하면 ListSorter, ListReverser 및 ListSearcher 클래스가 있습니다. ! ". 이것은 정확히 C ++에서 수행되는 작업이며 훌륭 합니다. 알고리즘은 데이터 구조와 분리되어 있으므로 자체 컨테이너를 작성하면 표준 라이브러리 에서 작동 하는 모든 알고리즘이 새 컨테이너에서 작동 합니다. .Net land에서는 끔찍해야하며 정렬하려는 모든 새 컨테이너에 대해 새로운 정렬 기능을 작성해야합니다.
Mankarse

14

Clean Code에 대해 언급했지만 좋은 아이디어가 포함되어 있지만 모든 메소드를 하위 메소드로 리팩토링하고 하위 메소드로 리팩토링하는 것에 대한 집착이 너무 멀리 있다고 생각합니다. 두 줄짜리 방법 대신에 20 개의 원 라이너를 선호합니다. 분명히 누군가는 그것이 깨끗하다고 ​​생각하지만 나에게는 원래 버전보다 훨씬 나빠 보입니다.

또한 다음과 같은 간단한 기본 사항을 대체합니다.

0 == memberArray.length

클래스 자체의 메소드를 호출하는 클래스 내에서

isEmpty()

의심스러운 "개선"IMHO입니다. 추가 : 차이점은 첫 번째 검사가 정확히 말한 것을 수행한다는 것입니다. 배열 길이가 0인지 여부를 확인합니다. 좋습니다 isEmpty(). 배열 길이도 확인할 수 있습니다. 그러나 다음과 같이 구현할 수도 있습니다.

return null != memberArray ? 0 == memberArray.length : true;

즉, 암시 적 null 검사가 포함됩니다! 배열이 null 인 경우 무언가가 비어있는 경우 공용 메소드의 경우 좋은 동작 일 수 있지만 클래스 내부에 대해 이야기 할 때 이것은 좋지 않습니다. 외부 캡슐화 는 필수이지만 클래스 내부 는 클래스 내에서 무슨 일이 일어나고 있는지 정확히 알아야합니다. 클래스 자체를 캡슐화 할 수 없습니다 . 암시적인 것보다 명시적인 것이 좋습니다.


긴 방법을 분석하거나 논리적 비교를하는 것이 좋지 않다는 것은 아닙니다. 물론 그것은 달콤한 맛이있는 곳에서 어느 정도해야할지 는 분명 맛의 문제입니다. 긴 방법을 세분화하면 더 많은 방법이 나오고 무료로 제공되지 않습니다. 모든 것이 단일 방법으로 이루어 졌다면 한 눈에 볼 수있을 때 실제로 진행중인 작업을 확인하려면 소스 코드를 뛰어 넘어야합니다.

심지어 어떤 경우에는 1- 라인 방법이 너무 짧아서 방법이 될 자격이 없다고 말할 수 있습니다.


6
나는 이것을 거의 문제로 보지 않습니다. 대개는 단일 방법으로 너무 많이 보지 않기 때문입니다. 그러나 일부 연구에 따르면 방법의 복잡성이 매우 낮 으면 복잡도가 약간 낮을 때보 다 버그 율이 약간 높습니다. enerjy.com/blog/?p=198
MIA

예, 이것은 Clean Code에서만 발생하는 문제입니다. 실제로 말한 것처럼 실제 방법은 너무 길다. 그러나 그 곡선을 보는 것은 흥미 롭습니다! 실제로 상황은 가능한 한 단순해야하지만 단순하지 않아야합니다.
Joonas Pulakka

1
두 번째 예제가 훨씬 더 읽기 쉽다는 것을 알았으며 공개 할 경우 그 형식 (또는 클래스 자체의 Length 속성과 비슷한 형식)은 필수입니다.
Robert Harvey

@Robert Harvey : 두 번째 예제는 훌륭한 퍼블릭 메소드이지만 클래스 자체에서 호출하는 것은 의문의 여지가 있습니다. 구현 방법을보기 전에 정확히 무엇을하는지 알 수 없기 때문입니다. 예를 들어 null을 확인할 수 있습니다. 위의 추가 내용을 참조하십시오.
Joonas Pulakka

@Joonas : 충분합니다.
Robert Harvey

13

"의견에 자유 로워"

주석은 확실히 좋은 것이지만 너무 많지 않으면 충분하지 않은 것만 큼 나쁘다. 왜? 사람들은 불필요한 의견이 너무 많으면 의견을 조정하는 경향이 있습니다. 완벽하게 자체 문서화 코드를 가질 수 있다고 말하지는 않지만 설명을 위해 주석이 필요한 코드를 작성하는 것이 좋습니다.


1
자체 문서화 코드는 확실히 좋습니다. 비록 간단한 계산 (반환 유형 또는 반환 값이 무엇인지 표현하기 위해)과 함께 주석을 갖는 것이 좋습니다. 그러나 주석에 코드 자체보다 더 많은 단어가 필요한 경우 코드를 다시 작성해야합니다.
sova

6
나는 sova가 이것을 넣는 방식에 동의해야합니다. 주석보다 깨끗한 코드가 좋습니다.
riwalk

4
당신은 여전히 ​​거기에 "왜"가 필요합니다!

오히려 이유를 설명하는 의견이 있습니다. 코드를 보았을 때 리버스 엔지니어링을 적게해야한다는 것을 의미합니다.
quick_now

12

유해한 것으로 간주되는 GoTo

상태 머신을 구현하는 경우 GOTO 문은 "구조화 된 프로그래밍"접근 방식보다 더 의미가 있습니다 (가독성 및 효율적인 코드). 새 직장에서 작성한 첫 번째 코드 조각에 단 하나의 고토 문 만이 포함되어있을 때 일부 동료들은 정말 걱정했습니다. 다행스럽게도이 사례에서는 실제로 최상의 솔루션이라는 것을 알기에 충분히 지능적이었습니다.

규칙에 대한 현명하고 문서화 된 예외를 허용하지 않는 "모범 사례"는 무섭습니다.


16
나는 하나의 goto 문 (당신이 언급 한 것처럼 여러 상태 머신 포함)없이 9 년 프로그래밍을 계속하고 있습니다. 새로운 아이디어로 마음을 확장하십시오.
riwalk

3
@Mathieu M.-동의-GOTO를 구조적 제어문과 혼합하는 것은 합리적이지 않습니다. (이것은 순수한 C였으며 문제가되지 않았습니다.
MZB

1
@ Stargazer2-간단한 FSM을 사용하면 상태를 변수에 넣고 색인으로 사용하여 프로 시저를 호출하는지 여부 (계산 된 GOTO와 동일하지 않습니까?)는 프로그램 카운터를 사용하는 것보다 더 명확하고 빠른 코드를 제공합니다 FSM 상태로. 나는 이것을 대부분의 상황에서 최고의 솔루션으로 주장하지 않고 어떤 상황에서는 최고의 솔루션으로 옹호하지 않습니다. 다른 접근 방식으로 마음을 확장하십시오.
MZB

5
@ MZB, 함수 호출도 계산 된 GOTO라는 데 동의하지 않습니까? for / while / if / else / switch 구성도 마찬가지입니다. 언어 디자이너는 이유 때문에 프로그램 카운터에 대한 직접적인 변경을 추상화합니다. goto를 사용하지 마십시오.
riwalk

3
상태 머신을 직접 구현하는 것은 반 패턴 일 수 있습니다. 말 그대로 상태와 전환을 표현하지 않고 상태 머신을 만드는 방법은 많이 있습니다. 예를 들어,import re
SingleNegationElimination

12

코드를 테스트 할 수 있도록하는 희생

내 코드를 테스트 할 수 있도록 많은 농구 대를 뛰어 넘었지만 선택을하지 않으면 내 척하지는 않습니다. 그러나 나는 사람들이 이것이 "모범 사례"라는 생각을 강요하는 것을 종종 듣는다. 이러한 관행에는 다음이 포함됩니다 (.Net의 언어로 작성되었지만 다른 언어에도 적용됨) .

  • 모든 클래스를 위한 인터페이스 만들기 두 배로 처리하는 클래스 (파일)의 수, 중복 코드를. 예, 인터페이스 프로그래밍 은 좋지만 공개 / 개인 지정자가 의도 한 것입니다.
  • 시작할 때 인스턴스화되지 않은 모든 클래스에는 팩토리가 필요합니다. 분명히, new MyClass()팩토리를 작성하는 것보다 훨씬 간단하지만, 이제는 팩토리를 만드는 방법을 개별적으로 테스트 할 수 없습니다. 이 사실이 아니라면, 나는 지금하는 팩토리 클래스 수의 1/20 만 만들 것입니다.
  • 모든 클래스를 공개로 설정하면 클래스에 액세스 지정자를 갖는 목적을 완전히 상실합니다. 그러나 비공개 프로젝트는 다른 프로젝트에서 액세스 (및 테스트) 할 수 없으므로 다른 옵션은 모든 테스트 코드를 동일한 프로젝트로 이동하여 최종 제품과 함께 릴리스하는 것뿐입니다.
  • 의존성 주입. 분명히 다른 모든 클래스에 필드를 사용하고 생성자 매개 변수를 사용하면 필요할 때 만드는 것보다 훨씬 많은 작업이 필요합니다. 그러나이 클래스를 더 이상 테스트 할 수 없습니다.
  • Single Responsibility Principle (단일 책임 원칙) 으로 인해 두통이 너무 많아서 본인의 대답으로 옮겼습니다 .

이 문제를 해결하려면 어떻게해야합니까? 우리는 언어 구조에 급격한 변화가 필요합니다 :

  • 수업을 조롱 할 수있는 능력이 필요합니다
  • 우리는 다른 프로젝트에서 내부 클래스의 개인 메소드를 테스트 할 수있는 능력이 필요합니다 (이는 보안 취약점처럼 보일 수 있지만 테스터가 테스터 클래스의 이름을 강요하면 문제가 발생하지 않습니다) .
  • 의존성 주입 (또는 서비스 위치)과 기존 팩토리 패턴과 동등한 것이 언어 의 핵심 부분 이어야합니다 .

간단히 말해, 우리 는 테스트 가능성을 염두에두고 처음부터 설계된 언어 가 필요 합니다 .


TypeMock에 대해 들어 본 적이 없다고 생각 하십니까 ? 그것은 조롱 클래스, 개인, 정적 (공장) 등을 허용합니다.
Allon Guralnek

@Allon : 나는 가지고 있지만 무료 가 아닙니다. 대부분의 사람들에게는 옵션이 아닙니다.
BlueRaja-대니 Pflughoeft

많은 팩토리 클래스를 작성 해야하는 경우 뭔가 잘못하고 있습니다. Smart DI 라이브러리 (예 : Autofac for C #)는 보일러 플레이트를 직접 작성하지 않고도 공장에서 Func <T>, Lazy <T>, Delegates 등을 활용할 수 있습니다.
gix

10

응용 프로그램을 계층으로 분리 데이터 계층, 비즈니스 계층, UI 계층

내가 이것을 싫어하는 주된 이유는이 방법을 따르는 대부분의 장소가 매우 부서지기 쉬운 프레임 워크를 사용하여 수행하기 때문입니다. IE UI 계층은 비즈니스 계층 개체를 처리하기 위해 수동으로 코딩되며, 비즈니스 계층 개체는 비즈니스 규칙 및 데이터베이스를 처리하기 위해 수동으로 코딩되며, 데이터베이스는 SQL이며 이미 변경을 싫어하는 "DBA"그룹에 의해 상당히 취약하고 관리됩니다.

왜 이것이 나쁜가요? 가장 일반적인 개선 요청은 "X 화면에 Y가있는 필드가 필요합니다."일 가능성이 높습니다. 쾅! 모든 단일 레이어에 영향을 미치는 새로운 기능이 있으며, 다른 프로그래머와 레이어를 분리하면 여러 사람과 그룹과 관련하여 매우 간단한 문제로 큰 문제가되었습니다.

또한, 나는 이런 식의 논쟁에 몇 번이나 있었는지 모른다. "이름 필드는 최대 길이 30으로 제한됩니다. UI 계층입니까, 비즈니스 계층입니까, 아니면 데이터 계층 문제입니까?" 그리고 백개의 논증이 있으며 정답은 없습니다. 대답은 동일하며 모든 레이어에 영향을 미칩니다. UI 바보를 만들고 모든 레이어를 거치지 않고 데이터베이스에서 실패해야하므로 사용자가 항목이 너무 길다는 것을 알 수 있습니다. 변경하면 모든 레이어 등에 영향을 미칩니다.

"층"도 누출되는 경향이 있습니다. 프로세스 / 시스템 경계 (IE 웹 UI 및 비즈니스 백엔드 로직)에 의해 계층이 물리적으로 분리 된 경우 모든 것이 합리적으로 작동하도록 규칙이 복제됩니다. 즉, 일부 비즈니스 로직은 "비즈니스 규칙"이지만 UI에 응답 할 수 있어야하기 때문에 UI에있게됩니다.

사용 된 프레임 워크 또는 사용 된 아키텍처가 작은 변경 및 유출에 탄력적이며, 즉 메타 데이터를 기반으로하고 모든 계층을 통해 동적으로 조정되면 덜 고통 스러울 수 있습니다. 그러나 대부분의 프레임 워크는 모든 작은 변경에 대해 UI 변경, 비즈니스 계층 변경 및 데이터베이스 변경이 필요하며 기술이 생성하는 것보다 더 많은 작업과 적은 도움을 필요로하는 엄청난 고통입니다.

아마 이것 때문에 비틀 거릴 것이지만, 거기에 있습니다 :)


+1, 가장 세부적인 세부 사항까지 나의 마지막 고용 장소처럼 들립니다! 계층 적 응용 프로그램을 원칙적으로 존중하지만 너무 많은 사람들이 이해가되지 않을 때은 총알처럼 취급합니다. 대부분의 비즈니스 소프트웨어는 엄청나게 적은 비즈니스 로직을 가지고 있으며 그 기능은 비교적 간단합니다. 이것은 계층 비즈니스 로직을 상용구 코드의 악몽으로 만들 수 있습니다. 쿼리가 비즈니스 논리이기 때문에 데이터 액세스와 비즈니스 논리간에 경계가 모호해질 수 있습니다.
maple_shaft

... 또한, 대부분의 상점은 UI 로직 또는 프리젠 테이션 로직 인식에 절대적으로 실패합니다. 일반적인 CRUD 응용 프로그램에 비즈니스 로직이 얼마나 적은지 이해하지 못하기 때문에 대부분의 로직이 프리젠 테이션 레이어에 프리젠 테이션 로직으로 존재할 때 무언가 잘못하고 있다고 생각합니다. 비즈니스 로직으로 잘못 식별 된 다음 사람들이 또 다른 서버 호출을 위해이를 서버로 푸시합니다. 씬 클라이언트는 프리젠 테이션 로직을 가질 수 있고 있어야합니다. dropDown3에서 option1이 선택된 경우 textField2를 숨 깁니다.
maple_shaft


7

사용자 사례 / 사용 사례 / 페르소나

 

나는 당신이 익숙하지 않은 산업을 프로그래밍 할 때 이것들의 필요성을 이해하지만, 그것들이 완전한 힘으로 구현되면 너무 회사가되어 시간 낭비가된다고 생각합니다.


7

80 자 / 라인 제한은 바보입니다

GUI 측면에서 가장 느린 러너 속도 (화면 해상도 제한 등)에 맞게 일부 타협이 필요하지만 그 규칙이 코드 형식에 적용되는 이유는 무엇입니까?

참조 ... 맨 오른쪽 픽셀 경계 외부의 가상 화면 공간을 관리하기 위해 만들어진 가로 스크롤 막대라는이 작은 발명품이있었습니다. 구문 강조 및 자동 완성과 같은 뛰어난 생산성 향상 도구를 개발 한 개발자는 왜이를 사용하지 않습니까?

물론, VT220 터미널의 피곤하고 오래된 한계를 따르는 * nix 공룡이 종교적으로 사용하는 CLI 편집기가 있지만 왜 우리는 같은 표준을 유지합니까?

80 문자 제한을 조이십시오. 공룡이 하루 종일 emacs / vim을 해킹 할 수있는 서사시라면 라인을 자동으로 감싸거나 CLI IDE에 가로 스크롤 기능을 제공하는 확장 기능을 만들 수없는 이유는 무엇입니까?

1920x1080 픽셀 모니터는 결국 표준이 될 것이며 전 세계 개발자들은 여전히 ​​프로그램을 시작했을 때 장로들에게 무엇을했는지를 제외하고는 왜 그런지에 관계없이 동일한 한계에 처해 있습니다.

80 개 문자 제한은 없습니다 가장 좋은 방법이지만 프로그래머의 아주 소수의 틈새 연습과 같은 취급 할 필요가 있습니다.

편집하다:

많은 개발자들이 마우스 스크롤이 필요하기 때문에 가로 스크롤 막대를 좋아하지 않는다는 것을 이해할 수 있습니다. 현대식 디스플레이를 사용하는 사람들에게는 열 너비 제한을 80보다 큰 수로 늘리지 않겠습니까?

800x600 컴퓨터 모니터가 대부분의 사용자에게 표준이되었을 때, 웹 개발자는 대다수를 수용하기 위해 웹 사이트 너비를 늘 렸습니다.


1
@ ___로 Nice GWB 로직을 사용하면 악의적 인 각도가됩니다. 따라서 hScroll을 싫어하면 col-width가 80 자로 제한되어야하는 유효한 이유가 있습니까? 160 또는 256이 아닌 이유는 무엇입니까? 우리 모두는 대부분의 개발자가 VT220 터미널을 폐기하고 puTTY로 교체했다고 가정 할 수 있으므로 너비를 프로그래밍 방식으로 확장 할 수 있습니다.
Evan Plaice

4
나는 우리가 80 자 제한에 충실하는 것을 선호합니다. 더 많은 수평 공간을 확보하자마자 나머지 문서와 나란히 추가 문서를 열어 보겠습니다. 네 가지 방식으로 스크롤 해야하는 것이 싫습니다. 또한 80 문자 캡으로 더 읽기 쉬운 코드를 작성해야한다는 것을 자주 알았습니다.
Filip Dupanović가

2
어떻게 인쇄하겠습니까?

5
죄송합니다-이것에 동의하지 않아야합니다. 나는 정말로 긴 줄을 싫어합니다. 더 많은 눈 움직임이 필요하고 마우스 제스처를 스크롤해야하며 줄 끝에서 미묘하게 작은 멍청한 것들을보기가 더 어렵습니다. 약 99 %의 경우 물건을 더 명확하고 읽기 쉬운 여러 줄 (짧은)에 걸쳐 실행하는 깔끔한 방법이 있습니다. 80 Chars는 임의적 일 수 있으며 "펀치 카드 시대에 그런 방식으로 이루어 졌기 때문에"위와 같은 이유로 대부분의 경우 내부에서 작업하기에 여전히 합리적인 프레임 워크입니다.
quick_now

3
2 칸 들여 쓰기 그리고 자동 들여 쓰기 추적기가있는 편집기를 사용하십시오. 나는 몇 년 동안 그런 식으로 해왔다. (올바른 모드의 이맥스가 여기에 도움이됩니다.)
quick_now

5

측정, 측정, 측정

따라서 미세 측정, 거리,하지만에 대한 분리 에 대한 작품뿐만 아니라 연속적인 제거를 측정, 성능 버그. 내가 사용하는 방법은 다음과 같습니다.

측정 측정 "지혜"의 출처를 추적하려고했습니다. 키가 충분한 비누 통을 가진 사람이 그것을 말했고, 이제는 여행합니다.


5

선생님은 소문자로 모든 식별자 (상수 제외)를 시작하도록 요구합니다 (예 :) myVariable.

나는 그것이 사소한 것처럼 보이지만 많은 프로그래밍 언어 대문자로 시작 하는 변수가 필요 합니다. 나는 일관성을 중요하게 생각하므로 대문자로 모든 것을 시작하는 것이 습관입니다.


9
나는 사람들이 현실 세계에서 사용하는 것이라고 주장했기 때문에 camelCase가 필요한 교사가있었습니다 ... 동시에 나는 내 작업에서 두 ​​개의 다른 그룹으로 프로그래밍하고있었습니다-두 그룹 모두 under_scores를 주장했습니다. 중요한 것은 그룹이 사용하는 것입니다. 그는 자신을 리드 프로그래머로 정의 할 수 있었으며 모든 저의 책에서 괜찮 았을 것입니다. 우리는 그의 관례를 따릅니다. 그러나 그는 다른 사람이없는 것처럼 항상 "실제 세계에서 일이 이루어지는 방식"으로 자신의 의견을 제시했습니다. 방법.
xnine

@xnine이 사이트에 아직 귀하의 의견을 평가할 충분한 담당자가 없으므로 승인에 대한
Maxpm

5
Camel case (첫 글자 소문자)는 Pascal case (대문자의 첫 글자)와 마찬가지로 일반적인 관례입니다. 대부분의 언어에서 camelCase는 개인 / 내부 변수에 사용되며 PascalCase는 클래스, 메서드, 속성, 네임 스페이스, 공용 변수에 사용됩니다. 다른 이름 지정 체계를 사용할 수있는 프로젝트를 준비하는 데 익숙해지는 것은 나쁜 습관이 아닙니다.
Evan Plaice

2
참고로 일부 언어는 변수의 첫 글자가 대문자인지 아닌지를 의미합니다. 그러한 언어 중 하나에서 첫 글자가 대문자 인 경우 변수는 상수로 취급됩니다. 변경하려고하면 오류가 발생합니다.
Berin Loritsch

1
에서 이동 , public 메소드와 클래스의 멤버는 대문자로 시작; 소문자가있는 개인용.
Jonathan Leffler

5

싱글 톤 사용

하나의 인스턴스 만 있어야 할 때. 나는 캔트 동의 더. 싱글 톤을 사용하지 말고 한 번만 할당하고 필요에 따라 포인터 / 객체 / 참조를 전달하십시오. 이것을하지 않을 이유는 전혀 없습니다.


2
그것은 싱글 톤에 대한 당신의 실제 입장에 대해 다소 혼란스러워했던 많은 부정적인 것입니다.
Paul Butcher

1
@Paul Butcher : 나는 싱글 톤을 싫어하고 절대 사용해서는 안된다

1
@ rwong : 개인적으로 나는 어떤 이유가 정당한 이유라고 생각하지 않습니다. 그냥 일반 클래스로 작성하십시오. 실제로 게으름 대신 싱글 톤을 사용하고 나쁜 습관이나 디자인을 장려 할 이유가 없습니다.

6
Singeltons 사용이 모범 사례라고 누가 말합니까?
Phil Mander

2
싱글 톤은 특히 운영 구조가 시작시 할당되고 채워진 경우 기본적으로 프로그램 실행 시간 내내 읽기 전용이됩니다. 이 경우 포인터 반대편의 캐시가됩니다.
Tim Post

5

부호없는 int를 반복자로 사용

부호있는 int를 사용하는 것이 훨씬 안전하고 버그가 덜 발생한다는 것을 언제 알게 될까요? 4-5가 4294967295라는 사실을 간과하기 위해 배열 인덱스가 양수 일 수 있다는 것이 왜 그렇게 중요합니까?


좋아, 이제 궁금해-왜 그렇게 말하니? 약간 바보 같은 느낌이 들었습니다. 명세서를 백업하기 위해 몇 가지 코드 예제를 제공 할 수 있습니까?
Paul Nathan

4
@Paul Nathan : 버그가있는 한 예제는 다음과 같습니다 : for (unsigned int i = 0; i <10; i ++) {int crash_here = my_array [max (i-1,0)];}
AareP

@ AareP : 확실하게-서명되지 않은 int가로 0감소 1하면 실제로 서명되지 않은 int가 저장할 수 있는 최대 양수 값으로 끝나는 사실을 참조한다고 가정합니다 .
Adam Paynter

1
@Adam Paynter : 예. 이것은 C ++ 프로그래머에게는 정상적인 것처럼 보이지만 "unsigned int"는 양의 유일한 숫자의 나쁜 "구현"입니다.
AareP

소형 임베디드 시스템에는 좋지 않습니다. 자주 서명되지 않은 정수는 더 작고 빠른 코드를 생성합니다. 컴파일러와 프로세서에 따라 다릅니다.
quick_now

4

메소드는 단일 화면보다 길어서는 안됩니다

나는 단일 책임 원칙에 완전히 동의하지만 사람들은 왜 "기능 / 방법이 최고 수준의 논리적 세분성에서 단일 책임을 가질 수 없다"는 의미로 인식 하는가?

아이디어는 간단하다. 기능 / 방법은 하나의 작업을 수행해야합니다. 해당 기능 / 방법의 일부를 다른 곳에서 사용할 수있는 경우 자체 기능 / 방법으로 잘라내십시오. 프로젝트의 다른 곳에서 사용할 수있는 경우 자체 클래스 또는 유틸리티 클래스로 이동하여 내부적으로 액세스 가능하게하십시오.

코드에서 한 번만 호출되는 27 개의 도우미 메서드가 포함 된 클래스를 갖는 것은 바보, 공간 낭비, 불필요한 복잡성 증가 및 막대한 시간 싱크입니다. 바쁜 리팩토링 코드를보고 싶지만 많이 생산하지 않는 사람들에게는 더 좋은 규칙처럼 들립니다.

여기 내 규칙이있다.

무언가를 달성하기위한 함수 / 메서드 작성

코드를 복사 / 붙여 넣기하려는 경우 해당 코드에 대한 함수 / 메소드를 만드는 것이 더 좋은지 스스로에게 물어보십시오. 함수 / 메소드가 다른 함수 / 메소드에서 한 번만 호출되는 경우, 실제로 함수 / 메소드가 처음에 있어야 할 시점이 있습니까 (향후 더 자주 호출 될 것임). 디버깅하는 동안 함수 / 메서드에 더 많은 점프를 추가하는 것이 중요합니까 (즉, 추가 된 점프로 인해 디버깅이 더 쉬워 지거나 더 어려워 집니까)?

200 줄 이상의 기능 / 방법을 면밀히 조사해야하지만 일부 기능은 한 줄의 작업 만 수행하고 프로젝트의 나머지 부분에서 추상화 / 사용할 수있는 유용한 부분이 포함되어 있지 않다는 것에 전적으로 동의합니다.

API 개발자의 관점에서 보았습니다 ... 새로운 사용자가 코드의 클래스 다이어그램을 보려는 경우, 프로젝트 전체에서 해당 다이어그램의 몇 부분이 의미가 있고 몇 개만 존재하는지는 알 수 있습니다. 프로젝트 내부의 다른 부분에 대한 도우미.

두 프로그래머 중 하나를 선택한다면 : 첫 번째 프로그래머는 너무 많은 것을 시도하는 함수 / 메서드를 작성하는 경향이 있습니다. 두 번째는 모든 기능 / 방법의 모든 부분을 가장 세분화 된 수준으로 나눕니다. 첫 손을 아래로 선택하겠습니다. 첫 번째는 더 많은 작업을 수행하고 (즉, 더 많은 응용 프로그램을 작성), 코드는 디버깅하기가 더 쉬워지고 (디버깅 중 함수 / 방법의 점프가 적어지기 때문에) 바쁜 작업을 수행하는 데 시간을 덜 낭비하게됩니다. 코드는 코드 작동 방식을 완벽하게 비교합니다.

불필요한 추상화를 제한하고 자동 완성을 오염시키지 마십시오.


이. 나는 한 번에 긴 함수를 여러 개로 리팩토링했으며, 거의 모든 것이 원래 코드의 거의 모든 매개 변수가 필요하다는 것을 깨달았습니다. 매개 변수 처리는 이전 코드로 돌아 가기가 더 쉬웠습니다.
l0b0

3
이것에 대한 한 가지 반론은 큰 메소드의 일부를 별도의 호출로 리팩토링하면 더 큰 메소드를 쉽게 읽을 수 있다는 것입니다. 메소드가 한 번만 호출 되더라도.
Jeremy Heiler

1
@ 제레미 어떻게? 코드 섹션을 추상화하고 자체 메소드에 배치하면 코드 행의 맨 위에 한 줄 주석을 배치하는 것보다 더 읽기 쉬운 방법은 무엇입니까? 해당 코드 블록이 해당 코드 섹션에서 한 번만 사용된다고 가정합니다. 대부분의 프로그래머가 코드를 읽을 때 코드의 작업 부분을 분해하거나 한 줄짜리 주석을 달아서 할 수없는 경우 수행 할 수있는 작업을 상기시키는 것이 실제로 그렇게 어려운가?
Evan Plaice

4
@Evan : 코드 조각을 함수에 효과적으로 넣으면 그 이름이 무엇인지 알 수 있기를 바랍니다. 이제 해당 코드가 호출되는 곳마다 알고리즘 자체 를 분석하고 이해 하는 대신 코드의 기능을 설명 하는 이름을 볼 수 있습니다. 잘 수행하면 코드를 읽고 쉽게 이해할 수 있습니다.
sbi

1
+1하면 더 많은 것을 줄 수 있습니다. 단일 함수에 1000 줄을 포함하는 C 코드 덩어리 (예 : 대규모 switch ()가있는 파서)에는 문제가 전혀 없습니다. 모든 작은 조각들을 쫓아 내고 그것들을 불러내는 것은 이해하기 어렵게 만듭니다. 물론 이것에도 한계가 있습니다 .... 현명한 판단이 전부입니다.
quick_now
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.