프로그래밍의 외관 대 내장 함수

무자비한 전투는 월드 와이드 웹에서 매일 발생합니다. 그것의 목표는 어떤 프로그래밍 풍미가 가장 좋은지 결정하는 것입니다: OOP 또는 FP? 나는 명령형 및 절차적 프로그래밍이 경쟁자의 일부가 아니라고 가정합니다.

주장은 사실에 입각한 것부터 관련이 없는 것, 완전히 어리석은 것까지 다양합니다. 몇 년 전, 저는 Martin Odersky(Scala 명성)의 비디오를 듣고 싶었습니다. 정확한 이야기도 주제도 기억나지 않습니다. 하지만 내가 기억하는 것은 서론입니다. 그는 FP가 OOP보다 더 인기가 있다고 설명했습니다. 왜냐하면 후자보다 전자에 전념하는 회의가 더 많았기 때문입니다.

그 당시에는 인기가 프로젝트를 수행하는 데 도움이 되는 관련 요소라고 생각하지 않았습니다. 이 글을 쓰는 시점에서 나는 여전히 그렇지 않습니다. 더군다나 전기 관련 회의가 없기 때문에 전기가 인기가 없다고 말하는 것과 같습니다. M. Odersky가 학술 연구에서 인기를 관련성으로 착각한 것이 유감입니다. 나는 그의 "논쟁"이후에 멈췄고, 지금까지 나는 그의 이야기를 다시는 본 적이 없다.

즉, 내 요점은 M. Odersky를 때리는 것이 아니라 일부 주장의 순수한 공허함을 강조하는 것입니다. 예를 들어, FP 애호가의 경우 불변성은 하나가 아닙니다. OOP도 이를 잘 활용할 수 있기 때문입니다. 유일한 차이점은 불변성이 FP의 요구 사항이라는 것입니다. 반대로 OOP를 너무 많이 밀면 모든 메소드가 클래스에 속해야 하는 Java와 같은 언어가 생성됩니다. 심지어 정적 메소드도 마찬가지입니다. 이 경우 클래스는 메서드에 대한 추가 네임스페이스일 뿐이며 OOP "값"을 가져오지 않습니다.

범위는 OOP 대 FP를 훨씬 능가합니다. 다음 스니펫을 고려하십시오.


fun router(repo: PersonRepository) = router {
    val handler = Handler(repo)
    GET("/person", handler::getAll)
}
    
class Handler(private val repo: PersonRepository) {
    fun getAll(r: ServerRequest) =
            ok().body(repo.findAll())
}
fun router(repo: PersonRepository) = router {
    val handler = Handler(repo)
    GET("/person/{id}", handler::getOne)
}
    
class  Handler(private val repo: PersonRepository) {
    fun getAll(r: ServerRequest) =
            ok().bodyValue(repo.findAll())
}

Obviously, the difference lies in the ok().body() vs. ok().bodyValue(). If you're unfamiliar with the Spring framework, you're unlikely to correctly identify the left snippet as WebMVC.fn and the right as Web Flux. It can be even more confusing if repo.findAll() is updated from blocking to non-blocking, as you won't spot any difference. You can only distinguish one from the other by looking at the package imports:

  • Blocking: org.springframework.web.servlet.function.*
  • Non-blocking: org.springframework.web.reactive.function.server.*

You can rewrite both above snippets using annotations instead of handlers.

@RestController
class PersonController(private val repo: PersonRepository) {

  @GetMapping
  fun getAll() = repo.findAll()
}
@RestController
class PersonController(private val repo: PersonRepository) {

  @GetMapping
  fun getAll() = repo.findAll()
}

Both snippets appear similar on the surface, but for the imports. Cosmetics are identical, while intrinsics - blocking vs. non-blocking - are fundamentally different.

Let's have a look at Kotlin coroutines. Here's a snippet taken from Kotlin's documentation:

measureTimeMillis {
    val one = somethingUsefulOne()                             // 1
    val two = somethingUsefulTwo()                             // 1
    runBlocking {
        println("The answer is ${one.await() + two.await()}")
    }
}


  • 함수가 일시 중단 계산을 가리킴

  • 코루틴 코드는 비동기식이지만 표면적으로는 명령형으로 보입니다.
    코 루틴의 장점은 다음과 같습니다.
  • 표면적으로는 중요해 보입니다. 따라서 이해하기 쉽습니다
  • .
  • 백그라운드에서 라이브러리가 코드를 비동기식으로 실행합니다
  • .

    코드에는 외형적 특성과 고유한 특성이 있습니다. 위의 몇 가지 예를 통해 완전히 직교한다는 것을 확신할 수 있기를 바랍니다. 다른 코스메틱으로 동일한 내재성을 달성할 수 있으며 그 반대의 경우도 마찬가지입니다.

    우리는 주석 대 "기능적"과 같이 화장품에 대해 끊임없이 논쟁하지만 본질적으로 개인 취향의 문제입니다. 문제를 해결하려면 액터, 비동기 등 내장 함수에 더 많은 시간을 할애해야 합니다.

    2022년 7월 31일 A Java Geek에서 원래 게시됨

    좋은 웹페이지 즐겨찾기