2020의 게시물 표시

Monad Transformer In Scala

안녕하세요~ 오늘은 Monad Transformer 에 대해서 포스팅해보려고 합니다 ㅎㅎ Monad Transformer 란? 자, 다음과 같이 간단한 코드가 있습니다. case class User ( id : String , bestFriendId : String ) def getUser ( userId : String ) : Future [ Option [ User ] ] = ? ? ? def getBestFriendOfUser ( userId : String ) : Future [ Option [ User ] ] = for { userOpt <- getUser ( userId ) bestFriendIdOpt = userOpt . map ( _ . bestFriendId ) bestFriendOpt <- bestFriendIdOpt match { case Some ( bestFriendId ) => getUser ( bestFriendId ) case None => Future . successful ( None ) } } yield bestFriendOpt getBestFriendOfUser 함수를 보면 Future 와 Option 이 함께 쓰이고 있는 것을 볼 수 있습니다. User 가 Option 과 Future 에 의해 2중으로 감싸져있기 때문에 실제 User 값에 대해 뭔가 연산을 수행하려면 상당히 성가시고 가독성도 떨어지게 됩니다. 결국 문제가 되는 부분은 “2중으로 감싸져있다” 는 점입니다. 즉, Future 와 Option 을 하나로 합친 타입을...

꼬리 재귀와 Trampoline In Scala

안녕하세요! 오늘은 스칼라 초심자를 대상으로 Tail Recursion (꼬리 재귀) 와 Trampoline 에 대해 포스팅하려고 합니다. 함수형 프로그래밍이나 모나드를 몰라도 이해할 수 있도록 노력해봤습니다~~ 간단하게 1부터 n 까지 더해주는 함수를 아래와 같이 작성한 뒤 실행 해봅시다. 스택오버플로우 에러가 뜨는 것을 확인할 수 있습니다. def unsafeSum ( n : Int ) : Int = if ( n == 1 ) 1 else n + unsafeSum ( n - 1 ) println ( s "sum = ${unsafeSum(100000)}" ) // 실행결과 // Exception in thread "main" java.lang.StackOverflowError // at dogs.MyApp$.unsafeSum(Main.scala:8) // at dogs.MyApp$.unsafeSum(Main.scala:8) // at dogs.MyApp$.unsafeSum(Main.scala:8) // at dogs.MyApp$.unsafeSum(Main.scala:8) 이번에는 아래와 같이 함수를 수정한 뒤에 실행 해봅시다. 스택오버플로우 없이 잘 동작하는 것을 확인할 수 있습니다. def safeSum ( n : Int , acc : Int ) : Int = if ( n == 0 ) acc else safeSum ( n - 1 , n + acc ) println ( s "sum = ${safeSum(100000, 0)}" ) // 실행결과 // sum = 705082704 대체 무슨 차이점 때문일까요? unsafeSum(5) 가 값을 반환하려면 일단 unsafeSum(4) 를 호출해서 결과를 얻은다음에 그 결과에 5 를 더해야합니다. ...

DDD Aggregate Pattern

오늘은 제가 가장 좋아하는 소프트웨어 설계 기법인 Aggregate Pattern 에 대해서 소개해드리겠습니다! Aggregate Pattern 이란? Aggregate Pattern 은 Eric Evans 의 Domain-Driven Design 에서 소개된 설계 패턴으로써 아주 강력하고 scalable 한 설계 지침을 제공합니다. Aggregate 를 제대로 설명하기 위해서는 Entity 등과 같은 DDD 의 다른 개념들도 같이 설명이 필요한데요. 이 글의 목적이 DDD 가 아니고 DDD 및 Aggregate 에 대한 개념적인 설명들은 인터넷에 많이 있으므로 이 글에서는 Aggregate Pattern 에 대한 통찰들을 전달하는데 집중하겠습니다. Aggregate 를 쉽게 말하자면 그냥 이름 그대로 연관 객체들의 묶음입니다. 즉, Aggregate 를 설계하는 것은 서로 연관된 객체들을 하나의 Aggregate 안으로 묶는다는 것이죠. 여기까지 말하면 사실 Aggregate 는 별로 의미가 없습니다. Aggregate 는 몇 가지 특징 및 제약사항들 을 가짐으로써 힘을 발휘하게 됩니다. Aggregate 는 내부의 도메인 객체들을 완전히 독점 소유합니다. 이게 무슨 말이냐면, 객체들은 오직 하나의 Aggregate 에만 속하게 되고 객체들의 lifetime 은 속해있는 Aggregate 의 lifetime 에 제한된다는 것입니다. (Aggregate 가 삭제되면 내부의 객체들도 같이 삭제됩니다.) Aggregate 는 항상 내부 객체들의 불변성을 강제해야만 합니다. 무슨 말인고 하니 Aggregate 내부는 항상 비지니스 룰에 부합하는 상태를 유지해야한다는 뜻입니다. Aggregate 각각이 transaction boundary 가 됩니다. 즉 하나의 트랜잭션에서는 하나의 Aggregate 만 변경할 수 있습니다. 여러 개의 Aggregate 들을 한 트랜잭션으로 변경하는 것은 불가능합니다. Aggregate 를 설계할 때는 위의 ...