2013-04-19 1 views
2

필자는 학습 연습으로 작성한 자바 애플리케이션에 scala로 이식하고있다. 그 중 일부는 TCP를 통해 직접 프로토콜을 사용하여 다른 시스템과 통신합니다. 이 프로토콜에는 해당 헤더 및 예고편이있는 2 개의 레이어 (응용 프로그램 및 전송)가 있습니다. 따라서 주어진 메시지는 다음과 같이 끝날 것입니다스칼라로 함수형 프로그래밍에서 부작용과 좋은 API 디자인 중 하나 선택

tHeader | aHeader | 메시지 | aTrailer | 트레일러 및 다음 계층에 전달 |

tTrailer 나는 헤더와 메시지를 완료 할 것

trait Layer{ 
    def write(s:String) : Unit 
    def read :String 
} 

각 레이어를 사용하여 생각했다. 그때 나는이 디자인에 감격했습니다

val layer = new TcpLayer with ApplicationLayer with TransportLayer 

처럼 구현에 결합 할 수있는 TransportLayerApplicationLayer있을 것, 그것은 의지에 따라 구성 요소를 재사용하는 저를 허용했다.

  • 부작용을 방지하기 위해, write 방법은 Unit를 반환하지해야하지만, 다음 전송해야하는 String 수정 : 그리고 내 딜레마 나타났다. 이렇게하면 부작용을 최소화하고 테스트가 쉬워 지지만 클라이언트 코드는 완료된 String을 소켓 자체에 보내야합니다 (이미 부작용이 있지만 주변에 아무런 영향도 미치지 않습니까?).
  • 클라이언트 코드가 '실행 및 종료'해야하므로 Layerwrite을 호출 할 수 있어야하며 수정 된 String (어쨌든 횡설수설 할 수도 있음)은 신경 쓰지 않아야합니다. 따라서 반환 값은 Unit이라고 생각합니다.

더 프로그래밍 기능적인 버전에 대한 통찰력이 있습니까?

답변

1

유일한 부작용은 다음 소켓에있는 경우 어떻게 이것에 대해 :

val layers = new TcpLayer with ApplicationLayer with TransportLayer 
socket.write (layers.write (message)) 
unitTestEngine.check (layers.write (message)) 

또는

클라이언트는 다음 작업을 할 수 layer이있는 경우 :

val layers = new TcpLayer (socket) with ApplicationLayer with TransportLayer 
layers.sink (layers.write (message)) 
unitTestEngine.check (layers.write (message)) 

sink Socket 인스턴스를 반환하는 메서드입니다.

관련 문제