어떻게 다음을 모두 가지고있는 시스템을 구축 할 :
- 변경 불가능한 객체에 순수한 함수 사용
- 더 이상 필요하지 않은 함수 데이터 만 전달하십시오 (즉, 큰 응용 프로그램 상태 객체가 없음).
- 함수에 너무 많은 인수를 사용하지 마십시오.
- 함수에 매개 변수를 패킹하고 압축을 풀기 위해 단순히 새로운 오브젝트를 구성하지 말고, 너무 많은 매개 변수가 함수에 전달되지 않도록하십시오. 하나의 객체로 함수에 여러 항목을 포장하려는 경우 해당 객체가 일시적으로 생성 된 것이 아니라 해당 데이터의 소유자가되기를 원합니다.
State 모나드는 규칙 # 2를 위반하는 것으로 보이지만 모나드를 통해 직조되어 있기 때문에 명확하지 않습니다.
어떻게 든 렌즈를 사용해야한다는 느낌이 들지만 비 기능 언어에 대해서는 거의 쓰여 있지 않습니다.
배경
연습으로, 기존 응용 프로그램 중 하나를 객체 지향 스타일에서 기능적 스타일로 변환하고 있습니다. 내가하려고하는 첫 번째 일은 응용 프로그램의 내부 코어를 최대한 많이 만드는 것입니다.
제가 들었던 한 가지는 순수한 기능 언어로 "상태"를 관리하는 방법입니다. 이것이 제가 주 모나드에 의해 수행된다고 생각하는 것은 논리적으로 여러분은 순수한 함수를 호출하는 것입니다. 함수를 반환하면 변경된 세계 상태를 반환합니다.
예를 들어, 순전히 기능적인 방식으로 "hello world"를 수행 할 수있는 방법은 일종의 프로그램과 같은 화면 상태를 전달하고 화면에 "hello world"가 인쇄 된 상태를 다시받습니다. 따라서 기술적으로 순수한 기능을 호출하고 부작용이 없습니다.
이를 바탕으로, 나는 내 응용 프로그램을 살펴 보았습니다. 1. 먼저 모든 응용 프로그램 상태를 단일 전역 객체 (GameState)에 넣었습니다. 2. 둘째, GameState를 변경할 수 없게 만들었습니다. 변경할 수 없습니다. 변경이 필요한 경우 새로운 변경을 구성해야합니다. 선택적으로 변경된 하나 이상의 필드를 사용하는 복사 생성자를 추가하여이 작업을 수행했습니다. 3. 각 응용 프로그램에 GameState를 매개 변수로 전달합니다. 함수 내에서 수행 할 작업을 수행 한 후 새 GameState를 생성하여 반환합니다.
순수한 기능적 코어와 외부의 루프를 통해 해당 GameState를 응용 프로그램의 기본 워크 플로 루프에 공급하는 방법.
내 질문:
이제 내 문제는 GameState에 약 15 개의 불변 객체가 있다는 것입니다. 가장 낮은 수준의 많은 기능은 점수 유지와 같은 일부 개체에서만 작동합니다. 점수를 계산하는 함수가 있다고 가정 해 봅시다. 오늘 GameState가이 함수로 전달되어 새로운 점수로 새로운 GameState를 만들어 점수를 수정합니다.
그것에 대해 뭔가 잘못 보인다. 이 함수에는 GameState 전체가 필요하지 않습니다. Score 객체 만 있으면됩니다. 그래서 점수를 전달하고 점수 만 반환하도록 업데이트했습니다.
그것은 말이되는 것처럼 보였으므로 다른 기능으로 더 나아갔습니다. 일부 함수는 GameState에서 2, 3 또는 4 매개 변수를 전달해야하지만 응용 프로그램의 외부 코어까지 패턴을 모두 사용함에 따라 점점 더 많은 응용 프로그램 상태를 전달합니다. 워크 플로 루프의 최상위에서 점수를 계산할 때까지 메서드 등을 호출하는 메서드를 호출하는 메서드를 호출합니다. 즉, 맨 아래의 함수가 점수를 계산하기 때문에 현재 점수가 모든 레이어를 통해 전달됩니다.
이제 수십 개의 매개 변수가있는 함수가 있습니다. 매개 변수 수를 낮추기 위해 해당 매개 변수를 객체에 넣을 수는 있지만 호출시 단순히 전달하지 않도록 객체가 아닌 해당 클래스가 상태 응용 프로그램 상태의 마스터 위치가되도록하고 싶습니다. 여러 매개 변수에 넣은 다음 포장을 풉니 다.
이제 문제가 내 기능이 너무 깊게 중첩되어 있는지 궁금합니다. 이것은 작은 함수를 원하기 때문에 발생합니다. 함수가 커질 때 리팩터링하여 여러 개의 작은 함수로 나눕니다. 그러나 그렇게하면 더 깊은 계층이 생성되고 외부 함수가 해당 객체에서 직접 작동하지 않더라도 내부 함수로 전달 된 모든 것이 외부 함수로 전달되어야합니다.
이 문제를 피하는 방식으로 단순히 GameState를 전달하는 것처럼 보였습니다. 그러나 함수에 필요한 것보다 더 많은 정보를 함수에 전달하는 원래 문제로 돌아 왔습니다.