Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.83 KB | None | 0 0
  1. Le refactoring c'est repasser sur son code pour le rendre bien plus robuste, simple à lire et standard.
  2.  
  3. C'est la qu'est l'intelligence du développeur, on différenciera le bon développeur du "mec qui suit les tuto sur openclassroom" avec ce genre de connaissance.
  4.  
  5. ### Exemple 1:
  6. Du code pris sur un projet, qui est vraiment pas mauvais :
  7.  
  8. ```kotlin
  9. /**
  10. * Get the data from the elastic search and convert the GeoNamesPlace to a Place
  11. * @param query Query with text to search and the fields to search in.
  12. * @param limit Limit of results
  13. * @return List of place
  14. */
  15. private fun searchPlace(isoLanguage: String, query: MultiMatchQueryBuilder, limit: Int): List<PlaceGeoNames>? {
  16. val placeList = arrayListOf<PlaceGeoNames>()
  17. val mapper = ObjectMapper()
  18. val searchRequest = SearchRequest(indexPrefix + isoLanguage.toLowerCase())
  19. val searchSourceBuilder = SearchSourceBuilder()
  20.  
  21. searchSourceBuilder.query(query)
  22. searchSourceBuilder.size(limit)
  23. searchRequest.source(searchSourceBuilder)
  24.  
  25. try {
  26. val searchResponse = Elasticsearch.search(searchRequest)
  27. val searchHits = searchResponse.hits.hits
  28. searchHits.forEach {
  29. val result = mapper.readValue<PlaceGeoNames>(it.sourceAsString)
  30. placeList.add(result)
  31. }
  32. } catch (exception: ElasticsearchException) {
  33. //if the index doesnt exists
  34. return null
  35. }
  36. return placeList
  37. }
  38. ```
  39.  
  40. Quels améliorations vous imagineriez ici ?
  41.  
  42. Dans le langage naturel ce que je fais ici c'est : Depuis une requete, la lancer et transformer les résultats dans un format qui me plait.
  43.  
  44. En gros je veux un truc comme ca dans mes reves les plus fous en 1 ligne :
  45. ```kotlin
  46. fun searchPlace(): List<Place>? {
  47. return query.search.results.transformTo(monFormat)
  48. }
  49. ```
  50.  
  51. Version factorisé (refactored)
  52. ```kotlin
  53. /**
  54. * Get the data from the elastic search and convert the GeoNamesPlace to a Place
  55. * @param query Query with text to search and the fields to search in.
  56. * @param limit Limit of results
  57. * @return List of place
  58. */
  59. private fun searchPlace(isoLanguage: String, query: MultiMatchQueryBuilder, limit: Int): List<PlaceGeoNames>? {
  60. try {
  61. query
  62. .toSearchRequest(indexPrefix + isoLanguage.toLowerCase(), limit)
  63. .search()
  64. .toHits()?.let {
  65. val mapper = ObjectMapper()
  66. val placeList = it.map {
  67. mapper.readValue<PlaceGeoNames>(it.sourceAsString)
  68. }
  69. return placeList
  70. }
  71. } catch (exception: ElasticsearchException) {
  72. //if the index doesnt exists
  73. return null
  74. }
  75. return null
  76. }
  77. ```
  78.  
  79. On a déplacé dans des lieux standards les fonctions qui vont nous servir ailleurs
  80.  
  81. ```kotlin
  82. //Avoiding .hits.hits that is ugly, but especially confusing and can generate errors
  83. fun SearchResponse.toHits(): Array<out SearchHit>? {
  84. return this.hits.hits
  85. }
  86.  
  87. //From a query, I wanted to
  88. fun MultiMatchQueryBuilder.toSearchRequest(index: String, limit: Int): SearchRequest{
  89. val searchSourceBuilder = SearchSourceBuilder().query(this).size(limit)
  90. return SearchRequest(index).source(searchSourceBuilder)
  91. }
  92.  
  93. //Simple wrapper, because extensions. More explicit to write, more simple, avoid some boilerplate
  94. fun SearchRequest.search(): SearchResponse {
  95. return Elasticsearch.search(this)
  96. }
  97.  
  98. ```
  99.  
  100. C'est stylé, mais on peut aller plus loin, je veux vraiment pouvoir parler simplement à mon code et qu'il appelle des fonctions standards.
  101.  
  102. > Objectif du swag
  103. > `query.search.results.transformTo(monFormat)`
  104.  
  105.  
  106. Grâce aux `Generics`, on peut le faire, on va justement pouvoir rendre notre code générique, peut importe le type sur lequel on travail actuellement (ici des `PlaceGeoNames`)
  107.  
  108. On va reprendre la partie qui est encore un peu moche pour la déporter dans une fonction générique qui va nous permettre de faire du fun en barre.
  109.  
  110. ```kotlin
  111. //Cette partie m'embete parce que c'est pas beau, je dois instancier des variables et mapper des choses que je sais que je devrais refaire ailleurs un jour pour un autre type.
  112. .toHits()?.let {
  113. val mapper = ObjectMapper() //Coucou je sais pas ce que je fais la, je suis méga standard
  114. val placeList = it.map {
  115. mapper.readValue<PlaceGeoNames>(it.sourceAsString) //le fun est la.
  116. }
  117. return placeList
  118. }
  119.  
  120. ```
  121. Donc si je prend ca et que je le déplace dans une extension générique cela me donnera ca :
  122.  
  123. ```kotlin
  124.  
  125. //Remember you came from this :
  126. fun SearchResponse.toHits(): Array<out SearchHit>? {}
  127.  
  128. //If you understand the function declaraction line, you can go to sleep and have nice refactoring dreams about every piece of code.
  129.  
  130. inline fun <reified T : Any>Array<out SearchHit>.transform() : List<T> {
  131. val mapper = ObjectMapper()
  132. return this.map {
  133. mapper.readValue<T>(it.sourceAsString)
  134. }
  135. }
  136.  
  137. ```
  138.  
  139. ET donc pour finir dans ma fonction principale j'ai ce joli code magnifique :
  140.  
  141. ```kotlin
  142. private fun searchPlace(isoLanguage: String, query: MultiMatchQueryBuilder, limit: Int): List<PlaceGeoNames>? {
  143. try {
  144. query
  145. .toSearchRequest(indexPrefix + isoLanguage.toLowerCase(), limit)
  146. .search()
  147. .toHits()?.transform<PlaceGeoNames>()
  148. } catch (exception: ElasticsearchException) {
  149. //if the index doesnt exists
  150. return null
  151. }
  152. return null
  153. }
  154. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement