2010-07-14 2 views
12

하스켈 및 기타 기능 언어에서 놀아 보면서 몇 가지 문제를 일반적인 용어로 설명함으로써 설계의 단순함을 알게되었습니다. 템플릿 프로그래밍의 많은 측면이 단순하지는 않지만, 일부 용도는 일반적으로 충분히 명확하므로 명확성 (특히 함수 템플릿)을 저해한다고 생각하지 않습니다. 필자는 템플릿이 현재 디자인을 간소화 할 수 있으며 동시에 미래의 약간의 저항을 자동으로 추가 할 수 있다고 생각합니다. 왜 그들의 기능을 도서관 작가에게 맡겨야합니까?지나친 일반화 란 무엇이라고 생각합니까?

한편, 일부 사람들은 전염병과 같은 템플릿을 피하는 것 같습니다. 제네릭 형식의 개념이 프로그래밍 공동체의 많은 부분에 국한된 10 년 전 저는 이것을 이해할 수있었습니다. 그러나 이제는 모든 정적 유형의 OO 언어가 하나의 형식 또는 다른 유형의 제네릭을 지원합니다. 추가 된 친밀감은 보수적 인 태도의 조정을 보증하는 것으로 보인다.

하나 개는 이러한 보수적 인 태도는 최근 나에게 표현되었다 :

당신은 필요한 것보다 더 일반적인 아무것도하지 않습니다 안 - 소프트웨어 개발의 기본 규칙을.

나는 이것이 솔직하게 말해야하는 것처럼 너무 경멸 스럽다는 것을 알기에 꽤 솔직히 놀랐다. 개인적으로 나는 하스켈과 같은 다른 언어를 사용하는 경우, 당신이 달리 지정하지 않는 한 모든 것이 일반적이라는 것을 자명 한 것으로부터 멀리 발견합니다. 즉, 나는이 관점이 어디서 비롯되는지 이해하고 있다고 생각합니다.

내 마음의 뒤에서, 나는 그 규칙이 어지러운 것처럼 느껴진다. 이제 그것이 최전선에 서서, 나는 전반적인 아키텍처에 비추어 항상 해석해 왔음을 알게됩니다. 예를 들어 클래스가있는 경우 언젠가 사용할 수있는 수많은 기능을로드하지 않으려 고합니다. 하나의 구체적인 버전 만 필요하다면 인터페이스를 만들지 않아도된다. (mockability가이 버전의 반론일지도 모르지만). 그런 것들 ...

그러나 내가하지 않는 것은 마이크로 레벨에서이 원리를 적용하는 것입니다. 특정 유틸리티 유형에 의존 할 이유가없는 작은 유틸리티 함수가있는 경우 템플릿을 만듭니다.

그래서 어떻게 생각하십니까? 지나친 일반화라고 생각하는 것은 무엇입니까? 이 규칙은 상황에 따라 적용 가능성이 다릅니 까? 이것이 규칙이라고 동의하는 것입니까?

+2

생활 코드를 만드시겠습니까? 하스켈 기반 웹 서버는 어떻게 작동합니까? 기억해 : "똑똑하고 잘 했어." http://www.joelonsoftware.com/items/2007/06/05.html –

+0

@James McNellis : 감사합니다. 나는 손가락을 가르키고 싶지 않거나 나는 단지 오래된 주장을 파헤 치려고하는 것처럼 보였다. 나는 진정으로 호기심이 많다. – Cogwheel

+1

여기 거래가 있습니다 - 당신은 대학생이 아닙니다. 진정한 필요성이 생길 때마다 특정 기능을 일반적인 기능으로 전환 할 수 있다고 믿습니다. 이제, 당신은 $ 50/hr 정도를 지불하는 일을하는 바쁜 성인입니다. 필요한 때에 만 일반화하는 것이 합리적이지 않습니까? 시간은 돈이다. –

답변

3

일반적으로 시간을 낭비 할 때 뭔가 이상하게 일반화됩니다. 당신이 장래에 일반적인 기능을 사용하려고한다면 아마 시간 낭비하지 않을 것입니다. 그것은 정말 간단합니다 [내 마음 속에].

한 가지주의해야 할 점은 소프트웨어를 일반화하는 것이 더 혼란 스럽다면 반드시 개선되지 않는다는 것입니다. 종종 상충 관계가 있습니다.

12

일반화가 지나치게 나를 미치게합니다. 나는 두려워하지 않는 템플릿 (아무데도 근처)와 나는 일반적인 솔루션을 좋아한다. 그러나 나는 또한 클라이언트가 지불하고있는 문제를 해결하는 것을 좋아한다. 1 주 프로젝트인데 왜 지금 새 세금과 같은 가능한 미래의 변화를 통해 일할뿐만 아니라 화성에 새로운 달이나 생명의 발견을 통해 일을 계속할 1 개월짜리 광상 기금에 자금을 지원합니까?

템플릿을 다시 가져 오면 클라이언트는 문자열과 숫자를 사용하는 함수 작성과 관련된 몇 가지 기능을 요구합니다. 당신은 두 가지 유형을 취하고 나머지 경우에는 내 특정 사례와 옳지 않을 수도있는 (요구 사항이 없어서) 옳은 일을하는 템플릿 솔루션을 제공하며, 나는 감사하지 않을 것입니다.나는 당신에게 돈을 지불하는 것 외에도, 테스트하기 위해 누군가를 지불해야하고, 문서화 할 누군가와, 앞으로 좀 더 일반적인 경우가 발생하면 미래의 제약 속에서 일할 누군가를 지불해야합니다.

물론 모든 일반화가 일반화를 넘어서는 것은 아닙니다. 모든 것이 가능한 단순해야하지만 더 간단하지는 않습니다. 필요에 따라 일반용이지만 일반용은 아닙니다. 우리가 감당할 수있는만큼 테스트되었지만 더 이상 테스트하지 않았습니다. 또한 "무엇이 변화하고 캡슐화 될지 예측하십시오." 이 모든 규칙은 간단하지만 쉽지는 않습니다. 이것이 개발자와 개발자를 관리하는 사람들에게 지혜가 중요한 이유입니다.

+0

이것은 좋은 관점이기도합니다.고객을위한 특정 코드를 생산하는 역할을 담당한다면 분명히 사양에 맞춰야 할 것입니다. 나는 당신이 디자인 자체에 더 많은 독립성을 가지고있는 상황에 주로 이것을 적용하고 있다고 생각합니다. – Cogwheel

10

동시에 수행 할 수 있고 코드가 최소한 분명하면 일반화가 항상 전문화보다 낫습니다.

XP 사용자가 YAGNI라고하는 원칙이 있습니다 - 당신은 필요 없을 것입니다.

을 당신이 지금 그것을 구현하지 않는, 나중에 기능을해야한다는 완전히, 완전히, 완전히 확신하더라도 :

wiki이 말을한다. 일반적으로, 그것은 결국 a) 당신이 결국 그것을 필요로하지 않거나, b) 실제로 필요한 것이 이전에 필요로했던 것을 기대했던 것과는 완전히 다르다.

이것은 코드에 유연성을 부여하지 말아야한다는 것을 의미하지 않습니다. 즉,에서 나중에 필요할 수도있는 것 같아서 을 기반으로 무언가를 과장하지 말아야한다는 의미입니다.

+1

이것이 주관적이지 않다면 나는 이것을 답으로 받아 들일 것이다. 첫 문장이 내 머리에 손톱을 친다. – Cogwheel

+0

# @ & %. 나는 정말로 내가 가지고 있으면 안되는 것을 일반화하는 일주일을 보냈다. 나는 아무것도 끝내지 못한다는 것은 이상한 일이 아닙니다. – mpen

0

마이크로 소프트에서 2 예에서가 과도하게 일반화 :
1) CObject (MFC) 그들 모두가 "실현"하는 데 사용됩니다
2) 객체 (닷넷)

대부분의 사람들이 사용하지 않는 C++의 제네릭. 사실, 모든 사람들이 (매개 변수/객체)를 사용하여 주어진 매개 변수에 대한 유형 검사를했습니다 ~

2

나는 프로그래밍의 두 가지 기본 원칙을 고려해야한다고 생각합니다 : KISS (간단하고 간단하게 유지) 및 DRY (반복하지 마십시오) . 대부분의 경우 처음부터 시작합니다. 필요한 기능을 가장 간단하고 간단하게 구현하십시오. 그것은 종종 내 요구 사항을 만족시킬 수 있기 때문에 충분합니다. 이 경우에는 간단합니다 (일반이 아님).

나는 비슷한 필요한 두 번째 (또는 세 번째 최대) 시간이 나는 콘크리트 실제 예에 따라 문제를 (함수, 클래스, 디자인, 무엇이든) 일반화하려고

-> 내가이 일반화 할 가능성은 낮습니다 단지 그 자체를 위해서. 다음 비슷한 문제 : 현재 그림에 우아하게 잘 맞으면 잘 해결할 수 있습니다. 그렇지 않다면 현재의 솔루션이 더 일반화 될 수 있는지 (너무 복잡하지 않고 너무 우아하지는 않은지) 확인합니다.

일반적인 솔루션이 필요하다는 것을 알고 있다고해도 비슷한 것을해야한다고 생각합니다. 몇 가지 구체적인 예를 들어서 그것에 기초한 일반화를 수행하십시오. 그렇지 않으면 "좋은"일반적인 해결책을 갖고있는 막 다른 골목에 빠지기는 너무 쉽지만 실제 문제를 해결하는 것은 불가능합니다.

그러나 예외적 인 경우가 있습니다.
a) 일반적인 솔루션이 거의 정확하게 동일한 노력과 복잡성을 띤 경우. 예 : generics를 사용하여 Queue 구현을 작성하는 것은 String에 대해서만 동일하게 수행하는 것이 훨씬 복잡하지 않습니다.
b) 일반적인 방법으로 문제를 해결하는 것이 더 쉽고 솔루션을 더 쉽게 이해할 수있는 경우 그것은 너무 자주 일어나지는 않습니다. 저는이 순간의 단순하고 실제적인 예를 생각해 낼 수는 없습니다 :- (그러나이 경우에도 예전에 구체적인 예를 가지고 분석하는 것은 반드시 IMO가되어야합니다.

경험상 구체적인 문제가 있다는 전제 조건을 극복 할 수는 있지만,이 경우에는 이미 경험을 통해 구체적이고 유사한 문제와 해결 방법을보고 생각한 것입니다.

시간이 있다면 Structure and Interpretation of Computer Programs을 살펴볼 수 있습니다. 일반성과 복잡성 간의 올바른 균형을 찾는 방법과 복잡성을 최소화하는 방법에 대한 흥미로운 내용이 많이 있습니다. 문제.

물론 다양한 민첩 프로세스는 비슷한 것을 권장합니다. 필요할 때 간단하고 리팩토링하는 것으로 시작하십시오.

6

너무 일반적인가? 나는 Generic Programming (원칙으로서)의 팬이라는 것을 인정해야하며, Haskell과 Go가 거기에서 사용한다는 생각을 정말 좋아한다.

동안 그러나, 비슷한 목표를 달성하기 위해 두 가지 방법이 제공됩니다 ++ C 프로그래밍 :

  • 일반 프로그래밍 : 템플릿의 방법으로, 컴파일 시간에 문제가 있더라도, 구현에 의존 등 ..
  • 객체 지향 프로그래밍 : 객체 자체 (클래스/구조체)가 아닌 함수에서의 문제를 배치하는 방식으로 조상, ...
  • 이제

, 사용하기? 확실히 어려운 질문입니다. 대부분의 경우 그것은 직감보다는 그다지 중요하지 않으며, 나는 어느 쪽인가의 남용을 확실히 보았습니다.

경험상 나는 함수/클래스가 작을수록 기본 목표가 높을수록 일반화하기가 더 쉬울 것이라고 말합니다. 예를 들어, 대부분의 애완 동물 프로젝트 및 직장에서 도구 상자를 가지고 다니고 있습니다. 함수/클래스의 대부분은 일반적인가 ... 방법으로 부스트 같은 비트) 반면에

// No container implements this, it's easy... but better write it only once! 
template <class Container, class Pred> 
void erase_if(Container& c, Pred p) 
{ 
    c.erase(std::remove_if(c.begin(), c.end(), p), c.end()); 
} 

// Same as STL algo, but with precondition validation in debug mode 
template <class Container, class Iterator = typename Container::iterator> 
Iterator lower_bound(Container& c, typename Container::value_type const& v) 
{ 
    ASSERT(is_sorted(c)); 
    return std::lower_bound(c.begin(), c.end(), v); 
} 

, 당신은 비즈니스 특정 작업에 도착 가까이, 가장 가능성이 당신이 될 수 있습니다 일반적인.

그래서 나는 최소한의 노력을 기울이는 원칙에 감사한다. 내가 수업이나 방법을 생각할 때, 나는 조금 뒤로 생각하고 조금 생각한다 :

  • 더 일반적인 것이 당연한가?
  • 비용은 어떻게됩니까?

는 anwsers에 따라, 나는들이 generic의 정도를 적응하고 약간 이상을 사용하는 것이 훨씬 비용이 들지 않습니다 때, 즉 내가 아닌 일반적인 충분한 방법을 사용하지 말고, 조기 잠금 방지하기 위해 투쟁 일반적인 것.

예 : 그것은 또한 더 관용적이다

void Foo::print() { std::cout << /* some stuff */ << '\n'; } 

// VS 

std::ostream& operator<<(std::ostream& out, Foo const& foo) 
{ 
    return out << /* some stuff */ << '\n'; 
} 

뿐만 아니라 그것은 더 일반적인 (출력에 어디 지정할 수 있습니다)입니다.

+1

_ 대부분의 경우 직감보다 중요하지 않음 : _ 동의 함. –

2

더 많은 단계에서 추상화를 중단 할 필요가 있다면 일반화가 필요합니다. 프로젝트 내 예, 내가 살고 : 그것은 3 계층 아키텍처에서 클라이언트에 제공되기 때문에 당신이없이 서버에 저장된 객체를 확인해야하므로

Object saveOrUpdate(Object object) 

이 방법은, 너무 일반적입니다 문맥.

관련 문제