클로저 : 왜 그렇게 유용할까요?
OO 개발자 로서 그 가치를 볼 수 있습니다. 어떤 부가 가치를 제공합니까? OO 세계에 가지고 있습니까?
클로저는 당신에게 추가적인 힘을주지합니다.
그들과 함께 달성 할 수있는 것은 무엇이든 그들 없이도 달성 할 수 있습니다.
그러나 코드를 더 명확하고 쉽게 만드는 데 매우 유용합니다. 그리고 우리 모두가 알다시피 깔끔하고 읽기 쉬운 짧은 코드는 디버그하기 약간가 약간 코드입니다.
가능한 사용에 대한 간단한 Java 예제를 제공합니다.
button.addActionListener(new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
System.out.println("Pressed");
}
});
(Java에 클로저가있는 경우) 다음으로 대체됩니다.
button.addActionListener( { System.out.println("Pressed"); } );
클래스의 일반화로 볼 수 있습니다.
당신의 수업은 어떤 상태를 가지고 있습니다. 메소드가 사용할 수있는 멤버 변수가 있습니다.
클로저는 포함 된 함수에 로컬 상태에 대한 액세스를 제공하는 더 편리한 방법입니다.
함수에서 사용하려는 지역 변수에 대해 알고있는 클래스를 정의 할 수 있으며 현재 보이는 모든 변수에 암시 적으로 액세스 할 수 있습니다.
OOP 언어로 멤버 메소드를 정의 할 때 클로저는 "이 클래스에서 볼 수있는 모든 멤버"입니다.
"적절한"클로저를 지원하는 언어는 기본 화를 사용하여 함수의 클로저는 "여기에서 볼 수있는 모든 변수"입니다. " 여기서 "가 클래스 인 경우 기존 클래스 메소드가 있습니다.
" 여기 "다른 함수 안에가 있으면 함수형 프로그래머가 클로저로 생각하는 것이 있습니다. 이제 함수는 부모 함수에서 볼 수있는 모든 것에 액세스 할 수 있습니다.
따라서 "함수는 클래스 내에서만 정의 될 수있다"는 어리석은 제한을 제거하는 일반 화일뿐입니다. 그러나 "함수는 선언 된 지점에서 보이는 모든 변수를 볼 수 있습니다"라는 생각을 유지합니다.
저에게있어 클로저의 가장 큰 이점은 작업을 시작하고 작업을 실행할 때 어떤 일이 발생해야 할 것인지 지정하는 코드를 실행할 때입니다. 일반적으로 작업이 끝날 때 실행되는 코드는 처음에 사용할 수있는 데이터에 액세스해야하며 클로저를 사용하면 쉽게 수행 할 수 있습니다.
예를 들어 JavaScript의 일반적인 용도는 HTTP 요청을 시작하는 것입니다. 시작하는 사람은 아마도 응답이 도착했을 때 일어나는 일을 제어하고 싶을 것입니다. 따라서 다음과 같이 할 것입니다.
function sendRequest() {
var requestID = "123";
Ext.Ajax.request({
url:'/myUrl'
success: function(response) {
alert("Request " + requestID + " returned");
}
});
}
JavaScript의 클로저로 인해 "requestID"는 성공 함수 내부에서 자동화됩니다. 요청 및 응답 함수를 작성하고 변수를 공유하는 방법을 보여줍니다. requestID를 인수로 전달하거나 requestID와 함수를 전달합니다.
이럴는 나중에 어느 시점에서 참조 할 코드 블록 과 컨텍스트 를 캡처 할 수 있고 필요할 때 / 만약 / 필요할 때 실행할 수 있다는 것입니다.
그들은 큰 문제가 될 것 같지 수 있으며 , 폐쇄 확실히 당신이 매일 일을 얻을 필요가 뭔가하지 않습니다 - 그들은하지만 수 쓰기에 코드를 훨씬 간단 코드와 청소기를 만들기 / 관리 할 수 있습니다.
[편집-위의 주석을 기반으로 한 코드 샘플]
자바 :
List<Integer> numbers = ...;
List<Integer> positives = new LinkedList<Integer>();
for (Integer number : integers) {
if (number >= 0) {
positives.add(number);
}
}
Scala (유형 추론 및 와일드 카드와 같은 다른 장점 중 일부를 건너 뛰기 때문에 클로저의 효과 만 비교합니다) :
val numbers:List[Int] = ...
val positives:List[Int] = numbers.filter(i:Int => i >= 0)
유감입니다. 사람들은 더 이상 에듀에서 스몰 토크를 배우지 거기에서 클로저는 제어 구조, 일련의 열거, 예외 처리가 사용됩니다. 좋은 예를 들어, 다음은 반복 작업 처리기입니다 (Smalltalk).
|actionQueue|
actionQueue := SharedQueue new.
[
[
|a|
a := actionQueue next.
a value.
] loop
] fork.
actionQueue add: [ Stdout show: 1000 factorial ].
그리고 Smalltalk를 읽을 수있는 사람들을 위해 JavaScript 구문에서 동일합니다.
var actionQueue;
actionQueue = new SharedQueue;
function () {
for (;;) {
var a;
a = actionQueue.next();
a();
};
}.fork();
actionQueue.add( function () { Stdout.show( 1000.factorial()); });
(보시다시피 구문은 코드를 읽는 데 도움이됩니다.)
편집 : 블록 내부에서 actionQueue가 참조되는 방식을 확인하십시오. 이는 분기 된 것 블록 작동합니다. 이것이 클로저를 사용하기 쉽게 만드는 이유입니다.
다음은 몇 가지 흥미로운 기사입니다.
- 국경을 넘어서 : 폐쇄 -Bruce Tate가 폐쇄를 계속합니다.
- 클로저 정의 -Neal Gafter (자바 클로저 제안 중 하나를 발명 한 사람 중 한 명)
클로저는 OO 세계에 아주 잘 맞습니다.
예를 들어 C # 3.0을 고려하십시오. 클로저 및 기타 많은 기능적 측면이 있지만 여전히 매우 객체 지향 언어입니다.
내 경험상 C #의 기능적 측면은 클래스 멤버의 구현 내에 머무르는 경향이 있으며, 내 개체가 노출되는 공용 API의 일부가 아닙니다.
따라서 클로저의 사용은 객체 지향 코드에서 구현 세부 사항이되는 경향이 있습니다.
단위 테스트 중 하나 ( Moq 에 대한 ) 의이 코드 스 니펫이 보여 주듯이 항상 사용합니다 .
var typeName = configuration.GetType().AssemblyQualifiedName;
var activationServiceMock = new Mock<ActivationService>();
activationServiceMock.Setup(s => s.CreateInstance<SerializableConfigurationSection>(typeName)).Returns(configuration).Verifiable();
C #의 클로저 기능이 아니었다면 입력 값 (typeName)을 Mock 기대의 일부로 지정하는 것이 매우 어려웠을 것입니다.
결론 쿼리 : "(폐쇄)가 OO 세계에 적합합니까?"
많은 언어에서 클로저는 일류 함수와 함께 OO 프로그램을 고안하기위한 기초를 제공합니다 : Javascript, Lua 및 Perl이 떠 오릅니다.
내가 익숙한 또 다른 "전통적인"OO 언어 인 Java에는 두 가지 주요 차이점이 있습니다.
- 함수는 일류 구조 가 아닙니다.
- Java에서 OO의 구현 세부 사항 (클로저가 내부적으로 사용되는지 여부)은 Javascript, Lua 및 Perl 에서처럼 개발자에게 직접 노출되지 않습니다.
따라서 Java와 같은 "전통적인 OO"언어에서 클로저 추가는 대체로 구문상의 설탕에 불과합니다.
컴파일 된 프로그래밍의 세계에서 클로저의 이점이 눈에 띄지 않을 수도 있습니다. JavaScript에서 클로저는 엄청나게 강력합니다. 그 이유는 두 가지입니다.
1) JavaScript는 해석 된 언어이므로 명령 효율성과 네임 스페이스 보존은 많은 양의 입력을 평가하는 대규모 프로그램이나 프로그램에서보다 빠르고 응답 성이 뛰어난 실행을 위해 매우 중요합니다.
2) JavaScript는 람다 언어입니다. 즉, JavaScript 함수에서 범위를 정의하는 첫 번째 클래스 개체이며 부모 함수에서 자식 개체에 액세스 할 수 있습니다. 변수는 부모 함수에서 선언되고 자식 함수에서 사용되며 자식 함수가 반환 된 후에도 값을 유지할 수 있기 때문에 중요합니다. 즉, 해당 함수의 마지막 반복에서 이미 정의 된 값으로 함수에서 변수를 여러 번 재사용 할 수 있습니다.
결과적으로 클로저는 엄청나게 강력하고 JavaScript에서 뛰어난 효율성을 제공합니다.
위의 예를 보면 비트를 추가 할 수 있습니다.
스타일, 상태를 숨기는 부분, 표현의 연결을 고맙게 생각하지만 이것으로는 충분하지 않습니다
간단하고 명시적인 코드에 대해 많은 것을 말할 수 있습니다.
- Scala, Perl 및 기타 Scheme 유형 언어는 언어 디자이너의 특정 사고 방식에 대한 일종의 속기 또는 "더 생산적"으로 만들도록 설계되었다고 생각합니다.
나는 단순성과 명시 성의 더 나은 방법으로 파이썬의 단순성과 자바 등의 초기 구문을 취할 것입니다.
좁은 공간에서 암호 체인 클로저를 작성하는 것은 매우 빠를 수 있습니다. 그러나 모든 것은 단순한 객체와 알고리즘으로 수행 될 수 있습니다.
폐쇄가 필요하지만 일류 시민임을 보증하기 위해 자주는 아닙니다.
참조 URL : https://stackoverflow.com/questions/1305570/closures-why-are-they-so-useful
'ProgramingTip' 카테고리의 다른 글
기본 클래스에서 하위 클래스 이름을 찾는 방법은 무엇입니까? (0) | 2021.01.06 |
---|---|
Android NDK의 엔디안 (0) | 2021.01.06 |
표준 라이브러리에서 가장 유용한 Python 모듈? (0) | 2021.01.05 |
이름 값 대신 클래스를 사용하는 jQuery 유효성 검사 (0) | 2021.01.05 |
들여 쓰기를 사용하여 HTML을 파일로 예쁜 인쇄하는 방법 (0) | 2021.01.05 |