[Groovy] 오리 타이핑과 정적 타이핑의 장점은 무엇입니까?


Answers

오리 타이핑에 대한 많은 의견들이 실제로 그 주장을 입증하지는 않습니다. 유형에 대해 "걱정할 필요가 없습니다"는 유지 보수 또는 응용 프로그램을 확장 가능하게 유지할 수 없습니다. 나는 Grails가 나의 마지막 계약과 그 매우 재미있는 것을 실제로 보았을 때 좋은 기회를 보았습니다. 누구나 "create-app"를 할 수 있다는 점에서 행복합니다. 슬프게도 결국 모두가 당신을 따라 잡습니다.

그루비는 나에게도 같은 방식으로 보인다. 확실히 매우 간결한 코드를 작성할 수 있으며, 속성, 컬렉션 등을 사용하여 작업하는 방법에는 멋진 설탕이 있습니다.하지만 도대체가 앞뒤로 전달되는 것을 모르는 비용은 점점 더 악화됩니다. 어떤 점에서 당신의 머리를 긁는 것은 왜 프로젝트가 80 %의 테스트와 20 %의 작업이되었는지 궁금해합니다. 여기서 교훈은 "더 작은"코드가 "더 읽기 쉬운"코드를 작성하지 않는다는 것입니다. 죄송합니다. 단순한 논리 - 직관적으로 더 많이 알아야만 더 많은 코드가 이해되는 과정이 더 복잡해집니다. GUI가 수년 간 지나치게 과장되어 버린 이유입니다. 확실히 보입니다. 그러나 WTH가 진행되는 것은 항상 명확하지 않습니다.

이 프로젝트에 참여한 사람들은 배운 교훈에 "어려움을 겪고"있는 것처럼 보였습니다. 그러나 T 타입의 단일 요소, ​​T의 배열, ErrorResult 또는 null 중 하나를 반환하는 메서드가있는 경우 오히려 명백 해집니다.

Groovy로 작업하는 한 가지가 저에게 도움이되었습니다.

Question

나는 Groovy에 대해 더 많은 것을 연구하고 실험하고 있으며 Groovy에서 Java로 할 수 없거나 할 수없는 것들을 구현하는 장단점에 대한 내 마음을 감쌀려고 노력하고 있습니다. 동적 인 프로그래밍은 여전히 ​​정적이고 강하게 타이핑 된 언어에 깊숙이 빠져 있기 때문에 여전히 저의 개념입니다.

Groovy는 나에게 duck-type 의 기능을 제공하지만 실제로 그 값을 볼 수는 없습니다. 오리 타이핑은 정적 타이핑보다 생산성이 더 좋습니다. 코드 연습에서 내가 그 이점을 이해할 수 있도록 도와 줄 수있는 일은 무엇입니까?

Groovy를 염두에두고이 질문을합니다. 그러나 모든 코드 캠프의 답변을 환영하기 때문에 반드시 멋있는 질문은 아닙니다.




@ 크리스 무리

정적 타이핑이 단순히 오리 유형보다 훨씬 생산성이 높은 것은 아닙니다. 오리 타이핑을 사용하면 항상 데이터에 올바른 방법이 있으며 Java 또는 Ruby에서 메소드 테스트를 통해 표시된다는 점에 대해 걱정해야합니다. 정적 유형 지정에서는 올바른 인터페이스 인 한 중요하지 않으므로 유형 간 테스트 및 변환이 번거롭지 않습니다.

미안하지만 그걸해야만 했어.




필자가 동적 유형 지정 언어를 단순히 추상적 인 기본 유형에서 상속하는 정적 유형 지정 형식으로 보는 경우에는 그다지 다르지 않습니다.

많은 사람들이 지적했듯이, 당신은 이것으로 이상해지기 시작하면 문제가 발생합니다. 누군가 단일 객체, 컬렉션 또는 null을 반환하는 함수를 지적했습니다. 함수가 복수가 아닌 특정 유형을 리턴하도록하십시오. 단일 대 모음에 대해 여러 기능을 사용하십시오.

문제는 누구나 나쁜 코드를 작성할 수 있다는 것입니다. 정적 타이핑은 위대한 안전 장치이지만 머리에 바람을 느끼고 싶을 때 헬멧이 방해가되는 경우가 있습니다.




IMHO, 변수 및 메서드를 일관된 방식으로 명명하는 것과 같은 규칙을 고수하면 오리 타이핑의 이점이 확대됩니다. Ken G 의 예를 생각하면 가장 잘 읽었을 것입니다.

class SimpleResults {
    def mapOfListResults
    def total
    def categories
}

A와 B가 다른 계약을 준수하는 경우 'calculateRating (A, B)'라는 일부 연산에서 계약을 정의한다고 가정 해 보겠습니다. 의사 코드에서는 다음과 같이 읽습니다.

Long calculateRating(A someObj, B, otherObj) {

   //some fake algorithm here:
   if(someObj.doStuff('foo') > otherObj.doStuff('bar')) return someObj.calcRating());
   else return otherObj.calcRating();

}

이것을 Java로 구현하려면 A와 B 모두 다음과 같은 것을 읽는 일종의 인터페이스를 구현해야한다.

public interface MyService {
    public int doStuff(String input);
}

게다가 평점 계산에 대한 계약을 일반화하려는 경우 (평점 계산에 다른 알고리즘이 있다고 가정 해 보겠습니다) 인터페이스를 만들어야합니다.

public long calculateRating(MyService A, MyServiceB);

덕 타이핑을 사용하면 인터페이스를 버리고 런타임시에 A와 B 모두 doStuff() 호출에 올바르게 응답 할 수 있습니다. 특정 계약 정의가 필요하지 않습니다. 이것은 당신을 위해 일할 수 있지만 그것은 또한 당신을 상대로 일할 수 있습니다.

단점은 일부 다른 사람이 코드를 변경 (즉, 다른 사람이 메서드 이름과 인수에 대한 암시 적 계약을 알고 있어야 함) 할 때 코드가 손상되지 않도록하기 위해 특별히주의해야한다는 것입니다.

이는 특히 구문 분석이 간결하지는 않지만 (예 : Scala 와 비교하여) Java에서 심각하게 악화됩니다. 이에 대한 반대의 예는 프레임 워크 의 SLOC 개수가 Rails 와 비슷하지만 테스트 코드가 테스트에서 유형 검사를 구현할 필요가 없으므로 줄이 적다는 Lift 프레임 워크입니다.




오리 타이핑은 가장 현대적인 IDE의 정적 검사를 무력하게하며, 입력시 오류를 지적 할 수 있습니다. 어떤 사람들은 이것이 이점이라고 생각합니다. IDE / 컴파일러에서 가능한 한 빨리 바보 프로그래머 트릭을 만들었다 고 말하고 싶습니다.

오리 타이핑 에 대한 나의 가장 최근 좋아하는 논쟁은 Grails 프로젝트에서 온다. DTO :

class SimpleResults {
    def results
    def total
    def categories
}

resultsMap<String, List<ComplexType>> 과 같은 것으로 판명되며, 생성 된 곳을 찾을 때까지 다른 클래스의 메소드 호출을 따라 가며 발견됩니다. 최종 호기심을 위해, totalList<ComplexType> 의 크기를 합한 것이며 categoriesMap 의 크기입니다

원래 개발자에게는 분명했을 지 모르겠지만, 가난한 유지 보수 담당자 (ME)는이 추적 코드를 많이 잃어 버렸습니다.




TDD + 100 % 코드 커버리지 + IDE 도구를 사용하여 지속적으로 테스트를 실행하므로 더 이상 정적 유형 지정이 필요하지 않습니다. 강력한 유형이 없으므로 단위 테스트가 매우 쉬워졌습니다 (모의 객체를 만들기 위해지도를 사용하기 만하면됩니다). 특히 Generics를 사용하면 차이점을 알 수 있습니다.

//Static typing 
Map<String,List<Class1<Class2>>> someMap = [:] as HashMap<String,List<Class1<Class2>>>

//Dynamic typing
def someMap = [:]   



Links