在编程中用不同的Cosmetics实现相同内在性的教程

48 阅读3分钟

关于编程中的Cosmetics与内在因素

代码有外观和内在的特点。请看例子,演示如何用不同的Cosmetics实现相同的内在性,反之亦然。

在万维网上每天都会发生一场无情的战斗。它的目标是决定哪种编程方式是最好的。OOP还是FP?我想,指令性编程和程序性编程并不在竞争者之列。

争论的范围从事实到无关紧要到完全愚蠢。几年前,我想听Martin Odersky(Scala的名声)的一段视频。我既不记得具体的讲座,也不记得主题。但我记得的是他的介绍:他解释说FP比OOP更受欢迎......因为专门讨论前者的会议比讨论后者的会议多很多。

当时,我不认为流行是一个帮助我交付项目的相关因素。在写这篇文章的时候,我仍然不这么认为。此外,这就好比说电力不受欢迎,因为没有任何专门的会议。恐怕奥德斯基先生把学术研究中的受欢迎程度误认为是相关的。我在他的 "论证 "之后就停止了,直到今天,我也没有再看他的讲座。

说到这里,我的意思不是要抨击M.Odersky,而是要强调一些论点的纯粹空洞性。例如,对于FP爱好者来说,它的不可变性并不是一个,因为OOP也可以很好地利用它。唯一的区别是,不变性是FP的一个要求。相反,把OOP推得太远会导致像Java这样的语言,其中每个方法都必须属于一个类,甚至是静态的。在这种情况下,类只是方法的一个额外命名空间:它们没有带来任何OOP的 "价值"。

这个范围远远超出了OOP与FP的关系。考虑一下下面的片段。

Kotlin
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())
}

class Handler(private val repo: PersonRepository) { fun getAll(r: ServerRequest) = ok().body(repo.findAll()) }

Kotlin
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())
}

class Handler(private val repo: PersonRepository) { fun getAll(r: ServerRequest) = ok().bodyValue(repo.findAll()) }

显然,区别在于ok().body()ok().bodyValue() 。如果你不熟悉Spring框架,你不可能正确识别左边的片段是WebMVC.fn,右边的是Web Flux。如果repo.findAll() 从阻塞式更新为非阻塞式,那就更令人困惑了,因为你不会发现任何区别。你只能通过查看软件包的导入来区分两者:

  • 阻塞式。org.springframework.web.servlet.function.*
  • 非阻塞。org.springframework.web.reactive.function.server.*

你可以用注解而不是处理程序来重写上面的两个片段:

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


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

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

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




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

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

这两个片段在表面上看起来都很相似,但在进口方面。化妆品是相同的,而内在因素--阻塞与非阻塞--则有根本的不同。

让我们来看看Kotlin的coroutines。下面是来自Kotlin文档的一个片段。

Kotlin

measureTimeMillis {
    val one = somethingUsefulOne()                             // 1
    val two = somethingUsefulTwo()                             // 1
    runBlocking {
        println("The answer is ${one.await() + two.await()}")
    }
}
  • 1:函数指向一个暂停的计算。

Coroutine代码在外观上看起来是命令式的,同时是异步的。这就是冠状病毒的优势。

  • 它在表面上看起来是命令式的;因此它足够容易理解。
  • 在幕后,库以异步方式运行代码。

代码具有外观和内在的特征。我希望上面的几个例子能让你相信,它们是完全正交的。你可以用不同的化妆品实现相同的内在特性,反之亦然。

我们一直在争论化妆品的问题,例如注释与 "功能",但这本质上是一个个人品味的问题。为了解决问题,我们需要在本征上花更多的时间:行动者、异步等。